日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux汇编和x86汇编,linux平台学x86汇编(四):从“hello world!”开始

發(fā)布時(shí)間:2025/3/20 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux汇编和x86汇编,linux平台学x86汇编(四):从“hello world!”开始 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【版權(quán)聲明:尊重原創(chuàng),轉(zhuǎn)載請保留出處:blog.csdn.net/shallnet,文章僅供學(xué)習(xí)交流,請勿用于商業(yè)用途】

匯編語言程序由定義好的段構(gòu)成,每個(gè)段有各自的目的。三個(gè)最常用的的段如下:數(shù)據(jù)段、bss段、文本段。文本段是可執(zhí)行程序內(nèi)聲明指令碼的地方,所有匯編程序都必須有文本段,數(shù)據(jù)段和bss段是可選的,但是在程序中經(jīng)常使用。數(shù)據(jù)段聲明帶有初始值的變量,bss段聲明使用0值初始化的數(shù)據(jù)元素,這些元素常用作匯編程序的緩沖區(qū)。下圖為匯編語言程序的布局。

GNU匯編器使用.section命令語句聲明段。.section語句只有一個(gè)參數(shù)——段類型。上圖的布局是匯編程序安排段的一般方式。bss段總是在文本段之前,數(shù)據(jù)段可以在文本段之后,但將其放在前面更容易閱讀和理解。

如其它高級語言一樣,匯編語言程序在鏈接為可執(zhí)行程序時(shí),鏈接器必須要知道程序中的起點(diǎn)是什么,就像c語言中的main函數(shù)一樣。GNU匯編器使用一個(gè)默認(rèn)標(biāo)簽_start作為應(yīng)用程序的入口點(diǎn),如果鏈接器找不到這個(gè)標(biāo)簽就會(huì)生成錯(cuò)誤消息。如果編寫被外部匯編語言或C語言程序使用的一組工具,需要使用.globl命令聲明每個(gè)函數(shù)段標(biāo)簽,.globl命令是聲明外部程序可以訪問的程序標(biāo)簽。所以,一般編寫匯編語言的基礎(chǔ)模板是這樣的:

.section.data

.section.bss

.section.text

.globl _start

_start:

有了模板之后就可以開始創(chuàng)建匯編語言程序,我們也像學(xué)習(xí)高級語言一樣,從最簡單的程序開始。

編寫匯編語言主要工作在編寫.text部分,該部分主要編寫要實(shí)現(xiàn)應(yīng)用程序的指令碼。匯編語言允許程序員使用助記符表示指令碼,助記符使程序員可以使用英語樣式的詞表示各個(gè)指令碼,匯編器可以很容易地把匯編語言助記符轉(zhuǎn)換為原始指令碼。這樣使得匯編程序員不必了解指令碼每個(gè)字節(jié)表示什么,子需要使用更加容易記憶的助記符(如push、mov、sub、call)來表示指令碼。比如下面這個(gè)指令碼例子:

55

89 E5

83 EC 08

C7 45 FC 01 00 00 00

83 EC 0C

6A 00

E8 D1 FE FF FF

可以寫為如下的匯編代碼:

push %ebp

mov %esp, %ebp

sub $0x8, %esp

movl $0x1, -4(%ebp)

sub $0xc, %esp

push $0x0

call 8048348

數(shù)據(jù)段

和高級語言一樣,編寫匯編語言程序都需要管理某種類型的變量,在匯編語言中數(shù)據(jù)段和bss段都提供了定義變量的方法。數(shù)據(jù)段是最常見的定義變量的位置。

在數(shù)據(jù)段中定義變量需要兩個(gè)語句:一個(gè)符號、一個(gè)命令。

符號類似于C語言程序中變量的名稱,它只是匯編器試圖訪問內(nèi)存位置時(shí)用作引用指針的一個(gè)位置。

命令實(shí)現(xiàn)為符號引用的數(shù)據(jù)元素保留多少字節(jié),類似于高級語言指定數(shù)據(jù)類型。匯編語言使用如下的命令:.ascii、.asciz、.byte、.double、.float、.int、.long、.octa、.quad、.short、.single。例如定義變量如下:

.section .data

msg:

.ascii “This is a test message”

數(shù)據(jù)段主要用于定義變量數(shù)據(jù),不過也可以使用命令.equ定義靜態(tài)數(shù)據(jù)符號,類似于高級語言的定義常量。例如:

.equ var 3

引用靜態(tài)數(shù)據(jù)時(shí),需要在變量名稱前加$符號,比如把var的值傳送到EAX寄存器:

movl $var, %eax

bss段

在bss段中定義數(shù)據(jù)元素和在數(shù)據(jù)段中定義有些不同,不需要指定特定數(shù)據(jù)類型。

GNU匯編器使用兩個(gè)命令聲明緩沖區(qū),.comm命令聲明未初始化的數(shù)據(jù)的通用內(nèi)存區(qū)域;.lcomm命令聲明未初始化的數(shù)據(jù)本地通用內(nèi)存區(qū)域,該區(qū)域不允許從本地匯編代碼之外進(jìn)行訪問。其使用格式為:

.comm symbol, length

symbol是賦給內(nèi)存區(qū)域的符號,length是內(nèi)存區(qū)域中包含的字節(jié)數(shù)量。

在bss段中聲明數(shù)據(jù)的一個(gè)好處是數(shù)據(jù)不包含在可執(zhí)行程序中,在數(shù)據(jù)段中定義數(shù)據(jù)必須包含在可執(zhí)行程序中。

下面來看看匯編語言的hello world 程序:

#hello.s sample program to print hello world information

.section .data #數(shù)據(jù)段聲明

msg:

.ascii "hello world!\n" #要輸出的字符串

len=.-msg #字符串長度

.section .text #代碼段聲明

# .global main

# main:

.global _start #指定入口函數(shù)

_start: #函數(shù)在屏幕上輸出hello world!

movl $len, %edx #第三個(gè)參數(shù): 字符串長度

movl $msg, %ecx #第二個(gè)參數(shù): hello world!字符串

movl $1, %ebx #第一個(gè)參數(shù): 輸出文件描述符

movl $4, %eax #系統(tǒng)調(diào)用號sys_write

int $0x80 #調(diào)用內(nèi)核功能

#下面為退出程序代碼

movl $0, %ebx #第一個(gè)參數(shù): 退出返回碼

movl $1, %eax #系統(tǒng)調(diào)用sys_exit

int $0x80 #調(diào)用內(nèi)核功能

編譯執(zhí)行結(jié)果如下:

$ as -o hello.o hello.s

$ ld -o hello hello.o

$ ./hello hello world!$

Linux 下的系統(tǒng)調(diào)用是通過中斷(int 0x80)來實(shí)現(xiàn)的。在執(zhí)行 int 0X80 指令時(shí),寄存器 eax 中存放的是系統(tǒng)調(diào)用號,而傳給系統(tǒng)調(diào)用的參數(shù)則必須按順序放到寄存器 ebx,ecx,edx,esi,edi 中,當(dāng)系統(tǒng)調(diào)用完成之后,返回值可以在寄存器 eax 中獲得。系統(tǒng)調(diào)用號4對應(yīng)的函數(shù)調(diào)用是

sys_write,在應(yīng)用上其函數(shù)定義如下:

ssize_t write(int fd, const void *buf, size_t count);

參數(shù) fd、buf 和 count 分別存在寄存器 ebx、ecx 和 edx 中,而系統(tǒng)調(diào)用號 SYS_write 則放在寄存器 eax 中,當(dāng) int 0x80 指令執(zhí)行完畢后,返回值可以從寄存器 eax 中獲得。

注意,如果使用gcc編譯的話有一個(gè)問題,gcc查找main標(biāo)簽而不是_start標(biāo)簽,所以把程序中的_start改為main直接使用gcc編譯鏈接就沒有問題了。

總結(jié)

以上是生活随笔為你收集整理的linux汇编和x86汇编,linux平台学x86汇编(四):从“hello world!”开始的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。