Linux kernel-彙編基礎
阿新 • • 發佈:2018-11-09
mov
ASSEMABLE C LANGUAGE movl %eax,%edx edx = eax; --->register mode movl $0x123,%edx edx = 0x123; --->immediate (0x123 is a value) movl 0x123,%edx edx = *(int32_t *)0x123 --->direct (0x123 is memory address) movl (%ebx),%edx edx = *(int32_t *)ebx --->indirect (fetch address from register ebx, and fetch the value from the address ) movl 4(%ebx),%edx edx = *(int32_t *)(ebx+4) --->displaced (address from register and offset) movb movw movl movq b,w,l,q: 8bit, 16bit, 32bit, 64bit
幾個重要指令pushl, popl, call, ret
pushl %eax == subl $4, %esp
movl %eax, (%esp)
popl %eax == movl (%esp), %eax
addl $4, %esp
call 0x12345 == pushl %eip(*)
movl $0x12345, %eip(*)
ret == popl %eip(*)
push - 棧頂地址減少8個位元組(64位,如果32位就是4個位元組) pop - 棧頂地址增加8個位元組(64位)
cs暫存器: 程式碼段暫存器
cs:rip - 總是指向下一條指令地址
call: 將當前cs:rip 的值壓入棧頂, cs:rip 指向的是被呼叫函式的入口地址
ret: 從棧頂彈出原來儲存在這裡的cs:rip的值,放到cs:rip
函式呼叫關係
//建立被呼叫者函式的堆疊框架
pushl %ebp //我的理解,在這裡,預設%esp就是比%ebp要加1的
movl %esp, %ebp
///被呼叫函式的函式體
///do sth
///
//拆除被呼叫者的堆疊框架
movl %ebp, %esp
popl %ebp
ret
分析case
... pushl $8 movl %esp, %ebp subl $4, %esp movl $8, (%esp) ...
#cat hello.c
#include <stdio.h>
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
#gcc -S -o hello.s hello.c
#cat hello.s
g:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
addl $3, %eax
popq %rbp
ret
f:
pushq %rbp
movq %rsp, %rbp
subq $8, %rsp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %edi
call g
leave
ret
main:
pushq %rbp
movq %rsp, %rbp
movl $8, %edi
call f
addl $1, %eax
popq %rbp
ret