為什么是匯編語(yǔ)言
本文關(guān)鍵詞:匯編語(yǔ)言,由筆耕文化傳播整理發(fā)布。
為什么是匯編語(yǔ)言 Posted on
語(yǔ)言的編譯過(guò)程就是把高級(jí)語(yǔ)言轉(zhuǎn)換成計(jì)算機(jī)能夠理解的二進(jìn)制機(jī)器指令的過(guò)程。這種轉(zhuǎn)換會(huì)產(chǎn)生一些效率不是很高的代碼。所以對(duì)一些效率要求高,或者對(duì)性能影響大的代碼都會(huì)直接用低級(jí)的匯編語(yǔ)言來(lái)編寫(xiě)。
匯編器是專(zhuān)門(mén)用來(lái)把低級(jí)匯編語(yǔ)言編譯成機(jī)器碼的二進(jìn)制程序或者目標(biāo)文件。
基于每個(gè)體系設(shè)計(jì)的cpu都會(huì)有其對(duì)應(yīng)的匯編語(yǔ)言,比如x86,arm
C語(yǔ)言的編譯過(guò)程
預(yù)處理->編譯(得到.s)->匯編(得到.o)->鏈接 (得到二進(jìn)制)
每一個(gè)c源文件都會(huì)得到一個(gè)目標(biāo)文件(.o),然后會(huì)把這些相關(guān)的目標(biāo)文件鏈接成一個(gè)二進(jìn)制文件。
其實(shí)每一種高級(jí)語(yǔ)言都會(huì)被編譯成匯編語(yǔ)言,最后得到二進(jìn)制文件,所以了解匯編語(yǔ)言是很重要的。
AT&T匯編用GNU GAS編譯,intel 匯編用NASM編譯
數(shù)據(jù)在內(nèi)存中存放的一個(gè)重要特點(diǎn):高位對(duì)應(yīng)高地址,低位對(duì)應(yīng)低地址
立即數(shù)
立即數(shù)相當(dāng)于高級(jí)語(yǔ)言中的常量,不用存儲(chǔ)在寄存器中,可以在表達(dá)是中直接使用
比如
movl $0x04,%ebx ;就相當(dāng)于把0x04這個(gè)值放入寄存器ebx
movl 0x04,%ebx ;就相當(dāng)于把從內(nèi)存地址0x04開(kāi)始的4個(gè)字節(jié)的內(nèi)容放入寄存器ebx
而在intel匯編中,立即數(shù)是不需要任何符號(hào)的,取內(nèi)存里面的值要加[ ]
movl %ebp,%eax #把ebp里面的內(nèi)容放到eax里面
movl -4(%ebp),%eax #從(ebp-4)這個(gè)地址開(kāi)始的4個(gè)字節(jié)的內(nèi)容放到eax里面,注意section:disp(base, index, scale)這種寫(xiě)法本身就表示地址,不是立即數(shù),就只能取值
間接操作數(shù)含有實(shí)際操作數(shù)的地址值,AT&T語(yǔ)法通過(guò)在一個(gè)操作數(shù)前添加*來(lái)指定一個(gè)間接操作數(shù)。只有在間接跳轉(zhuǎn)/調(diào)用指令時(shí)才使用間接操作數(shù)。
jmp *%ebx #ebx的值是跳轉(zhuǎn)的目標(biāo)位置
jmp *(%ebx) #從ebx值的指定的地址處讀取跳轉(zhuǎn)的目標(biāo)位置
在一個(gè)目標(biāo)文件中text區(qū)從地址0開(kāi)始,,隨后是data區(qū),然后是bss區(qū)
每個(gè)區(qū)都有意個(gè)位置計(jì)數(shù)器,它會(huì)對(duì)每個(gè)匯編進(jìn)該區(qū)的字節(jié)進(jìn)行計(jì)數(shù);.align可以改變位置計(jì)數(shù)器的值
bss區(qū)用于存放未被初始化的變量或者作為局部公共變量存儲(chǔ)空間
.lcomm用于在bss區(qū)定義一個(gè)符號(hào)
.comm用于在bss區(qū)定義一個(gè)公共符號(hào)
在程序運(yùn)行之前不能在bss區(qū)放置數(shù)據(jù),因?yàn)槌绦蜷_(kāi)始之前,所有bss區(qū)的內(nèi)容都會(huì)被清零
absolute區(qū)在重定位后地址保持不變,兩個(gè)目標(biāo)文件中absolute區(qū)中地址相同的數(shù)據(jù)會(huì)因?yàn)橹丿B而被一個(gè)覆蓋
特殊符號(hào)'.'表示as匯編的當(dāng)前地址因此 mylab: .long . 表示把mylab它自己所處地址的值,給'.'賦值如同‘.org'的作用,因此 .=.+4和 .space 4一樣
語(yǔ)句
可以是只含空格 制表符 換行符的空行,也可以是1)賦值語(yǔ)句 2)偽操作符語(yǔ)句3)機(jī)器指令語(yǔ)句
1)賦值語(yǔ)句
BOOTSEG = 0x70C0
2)偽操作符語(yǔ)句
以一個(gè)點(diǎn)開(kāi)始的匯編語(yǔ)句叫做,匯編命令(偽指令,指示符)。偽指令的地址是點(diǎn)符號(hào)出現(xiàn)處,機(jī)器指令第一個(gè)字節(jié)的位置。它本身不產(chǎn)生任何代碼。
.globl begtext, begdata, begbss, endtext, enddata, endbss
3)機(jī)器指令
每個(gè)機(jī)器指令前面都可以有一個(gè)標(biāo)號(hào)。機(jī)器指令可以由 標(biāo)號(hào) + 指令助記符 + 操作數(shù) 三個(gè)字段組成。
任何標(biāo)號(hào)定義都會(huì)取用位置計(jì)數(shù)器的當(dāng)前值。標(biāo)號(hào)本身不占內(nèi)存,它的地址是后面的機(jī)器指令的第一個(gè)字節(jié)的位置,我通過(guò)gdb的info line查看了。(位置計(jì)數(shù)器我還是不太清楚到底是干什么的)
AT&T匯編語(yǔ)句以換行符或者;結(jié)束,最后的一個(gè)語(yǔ)句必須以換行符結(jié)束
PS:intel匯編都是以換行符結(jié)束的,所以intel匯編可以用;來(lái)注釋
注釋
intel 匯編的注釋是!或者;
AT&T的注釋是shell 風(fēng)格的#或者c風(fēng)格/* */或者c++風(fēng)格的//
匯編語(yǔ)言的一個(gè)突出優(yōu)點(diǎn)就是可以使用符號(hào)(symbol),正是因?yàn)橛辛朔?hào)匯編語(yǔ)言才變得容易理解,便于記憶(相對(duì)于機(jī)器指令而言)
標(biāo)號(hào)是符號(hào)的一種
movz: 零擴(kuò)展,高位用0補(bǔ)齊
movb $0x80,%bl
movzbw %bl,%ax
ax就變成了0x0080
movs: 符號(hào)擴(kuò)展,高位用原最高位補(bǔ)齊
movb $0x80,%bl
movsbl %bl,%ax
ax就變成了0xFF80
本文關(guān)鍵詞:匯編語(yǔ)言,由筆耕文化傳播整理發(fā)布。
本文編號(hào):510348
本文鏈接:http://sikaile.net/wenshubaike/dxkc/510348.html