原文見part2
<a name="GxXu3"></a>
<a name="AwVRs"></a>
術(shù)語與概念
因?yàn)槭盏酱罅孔x者的述求糕珊,說第一篇文章不夠清晰,所以本文以及后面將補(bǔ)充這部分內(nèi)容澜公。<br />寄存器 - 寄存器是處理器內(nèi)部少量的存儲(chǔ)喇肋。處理器的重點(diǎn)工作是處理數(shù)據(jù)。處理器可直接從內(nèi)存獲取數(shù)據(jù)甚侣,但是這樣操作速度很慢殷费。所以處理器有自己內(nèi)部受限數(shù)量的數(shù)據(jù)存儲(chǔ)即寄存器低葫;<br />小端存儲(chǔ) - 小端存儲(chǔ)是最低有效字節(jié)的地址最泻傩;<br />大端存儲(chǔ) - 大端存儲(chǔ)和小端存儲(chǔ)相反窒盐;<br />系統(tǒng)調(diào)用 - 是用戶級(jí)程序要求操作系統(tǒng)為其執(zhí)行某些操作的方式。可以從系統(tǒng)表中看到娶靡。<br />棧 - 處理器僅有很少的受限數(shù)量的寄存器姿锭。堆棧是內(nèi)存可尋址專用寄存器的連續(xù)區(qū)域如RSP, SS, RIP等。<br />段 - 每個(gè)匯編程序由段組成轮纫。有以下部分:
- data - 用于生成已初始化的變量或靜態(tài)變量掌唾;
- bss - 用于生命未初始化過的變量忿磅;
- text - 用于代碼
通常情況下葱她,有16個(gè)通用寄存器- rax, rbx, rcx, rbp, rsp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15. 當(dāng)然匯編編程相關(guān)的術(shù)語和概念的完整列表。若下文遇到不熟悉的術(shù)語時(shí)搓谆,我們將會(huì)解釋相關(guān)概念豪墅。
<a name="bD7WU"></a>
數(shù)據(jù)類型
基礎(chǔ)的數(shù)據(jù)類型有字節(jié)(bytes), 字(words),雙字(doublewords), 四字(quadwords)以及雙四字螃诅。<br />1byte是8bits术裸,1字是2bytes亭枷,雙字是4bytes叨粘,瘤睹。轰传。瘪撇。<br />目前本文只會(huì)涉及整型,整型分為兩種:無符號(hào)整型和有符號(hào)整型倔既。無符號(hào)雙字整型范圍為0 to 2^32 – 1恕曲,<br />有符號(hào)雙字整型為–2^31 to +2^31 – 1...
<a name="ZxT7U"></a>
段
正如前文所述,每個(gè)匯編程序由段組成渤涌,它可以是數(shù)據(jù)段佩谣、文本段和BSS段的組合,首先我們關(guān)注數(shù)據(jù)段实蓬,有以下例子:
section .data
num1: equ 100
num2: equ 50
msg: db "Sum is correct", 10
這段代碼的意思似乎很明確茸俭,但其中equ, db是什么意思呢?實(shí)際上NASM支持一些偽指令:
- DB, DW, DD, DQ, DT, DO, DY和DZ - 用于生成已初始化數(shù)據(jù)安皱,例如:
;; Initialize 4 bytes 1h, 2h, 3h, 4h
db 0x01,0x02,0x03,0x04
;; Initialize word to 0x12 0x34
dw 0x1234
- RESB, RESW, RESD, RESQ, REST, RESO, RESY和RESZ - 用于聲明未初始化變量瓣履;
- INCBIN - 導(dǎo)入外部二進(jìn)制文件练俐;
- EQU - 定義靜態(tài)變量袖迎,例如:
;; now one is 1
one equ 1
- TIMES - 重復(fù)指令或數(shù)據(jù)。
<a name="Sz8BT"></a>
算術(shù)操作
- ADD - 整型加法
- SUB - 減法
- MUL - 無符號(hào)乘法
- IMUL - 有符號(hào)乘法
- DIV - 無符號(hào)除法
- IDIV - 有符號(hào)除法
- INC - 加1
- DEC - 減1
- NEG - 負(fù)
<a name="CjNQr"></a>
控制流
cmp指令用于執(zhí)行兩個(gè)值間的比較腺晾,該指令用于條件跳轉(zhuǎn):
;; compare rax with 50
cmp rax, 50
cmp指令僅是比較兩個(gè)值燕锥,沒有任何副作用,并且不會(huì)根據(jù)比較結(jié)果執(zhí)行任何操作悯蝉。對(duì)于比較后的任何操作归形,這里有一系列條件跳轉(zhuǎn)指令:
- JE - 如果相等
- JZ - 如果為0
- JNE - 如果不相等
- JNZ - 如果非零
- JG - 如果第一個(gè)數(shù)大于第二個(gè)數(shù)
- JGE - 大于等于
- JA - 和JG類似,不過是針對(duì)無符號(hào)
- JAE - 和JGE鼻由,但是針對(duì)無符號(hào)類型
例如C中的if/else語句聲明如下:
if (rax != 50) {
exit();
} else {
right();
}
那么在匯編中則是:
;; compare rax with 50
cmp rax, 50
;; perform .exit if rax is not equal 50
jne .exit
jmp .right
這里也有無條件跳轉(zhuǎn)如:
JMP label
具體例子如:
_start:
;; ....
;; do something and jump to .exit label
;; ....
jmp .exit
.exit:
mov rax, 60
mov rdi, 0
syscall
<a name="ClEnw"></a>
示例
section .data
; Define constants
num1: equ 100
num2: equ 50
; initialize message
msg: db "Sum is correct\n"
section .text
global _start
;; entry point
_start:
; set num1's value to rax
mov rax, num1
; set num2's value to rbx
mov rbx, num2
; get sum of rax and rbx, and store it's value in rax
add rax, rbx
; compare rax and 150
cmp rax, 150
; go to .exit label if rax and 150 are not equal
jne .exit
; go to .rightSum label if rax and 150 are equal
jmp .rightSum
; Print message that sum is correct
.rightSum:
;; write syscall
mov rax, 1
;; file descritor, standard output
mov rdi, 1
;; message address
mov rsi, msg
;; length of message
mov rdx, 15
;; call write syscall
syscall
; exit from program
jmp .exit
; exit procedure
.exit:
; exit syscall
mov rax, 60
; exit code
mov rdi, 0
; call exit syscall
syscall