彙編常用的寄存器有:
data register:EAX,EBX,ECX,EDX
segment register: CS, DS, EX, FS, GS, SS
index register: ESI, EDI(表示源和目的
pointer register: EIP, ESP, EBP
EIP 爲指令指針, ESP 爲堆棧指針,EBP爲基址指針寄存器,用來標識棧中某一固定位置,當調用子過程中有參數時常用EBP來容易分出參數的位置。對於跳轉常用的幾個指令有:call,jmp, ret.
jmp a = move a EIP 將目的地址放到EIP 中然後執行
call = push EIP + jmp 即先將下一條指令壓棧,然後跳轉
ret = pop EIP 即將要返回的地址放到EIP中
舉個具體例子(example.c):
int add(int a, int b){
return a+b;
}
int main(){
add(7,9);
}
#gcc -o a.out example.c
#objdump -d a.out
08048394 <add>:
8048394: 55 push %ebp
8048395: 89 e5 mov %esp,%ebp
8048397: 8b 45 0c mov 0xc(%ebp),%eax
804839a: 03 45 08 add 0x8(%ebp),%eax
804839d: 5d pop %ebp
804839e: c3 ret
0804839f <main>:
804839f: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483a3: 83 e4 f0 and $0xfffffff0,%esp
80483a6: ff 71 fc pushl -0x4(%ecx)
80483a9: 55 push %ebp
80483aa: 89 e5 mov %esp,%ebp
80483ac: 51 push %ecx
80483ad: 83 ec 08 sub $0x8,%esp
80483b0: c7 44 24 04 09 00 00 movl $0x9,0x4(%esp)
80483b7: 00
80483b8: c7 04 24 07 00 00 00 movl $0x7,(%esp)
80483bf: e8 d0 ff ff ff call 8048394 <add>
80483c4: 83 c4 08 add $0x8,%esp
80483c7: 59 pop %ecx
80483c8: 5d pop %ebp
80483c9: 8d 61 fc lea -0x4(%ecx),%esp
80483cc: c3 ret
80483cd: 90 nop
80483ce: 90 nop
80483cf: 90 nop
對於子過程add, 在棧中的位置如下
高-----------------低
| 9 | 7 | 80483c7 | %ebp |
——————————————————
過程調用進入子過程時一般都有下面兩條指令:
push %ebp,
mov %esp, %ebp
爲什麼使用ebp呢 這是因爲ESP的內容很容易改變,而使用ebp可以作爲固定參考點,來獲取參數