有人可以解释反汇编代码中的这些步骤会做什么.我有一个大概,但我仍然感到困惑.我知道前两个指令设置了堆栈,而eax将是一个返回值,但就是这样.
我正在寻找的是以下步骤的目的:
push %ebp - base stack frame pointer
mov %esp, %ebp - stack pointer
sub $0x10, %esp - subtracts 16 from ?
mov 0x8(%ebp), %eax - ?
imul 0xc(%ebp), %eax - multiply 12 and ?
mov %eax, -0x4(%ebp) - ?
mov -0x4(%ebp), %eax - puts -0x4(%ebp) not sure what that would be , into eax making it the return value?
leave
ret
Run Code Online (Sandbox Code Playgroud)
; Standard prolog: stack frame setup
push ebp ; save the old frame pointer
mov ebp, esp ; set the frame pointer to the current top of the stack
sub esp, 0x10 ; make space for 16 bytes of local variables
; Do the stuff
mov eax, [ebp+8] ; copy the first parameter in eax
imul eax, [ebp+0xc] ; multiply eax with the second parameter
mov [ebp-4], eax ; move the result to the first local variable
mov eax, [ebp-4] ; move it back to eax (?) => set it as return value
; Standard cdecl epilog - clean up locals & return
leave ; restore the old frame pointer
; same as: mov esp, ebp
; pop ebp
ret ; return
Run Code Online (Sandbox Code Playgroud)
(很抱歉将其更改为英特尔表示法,但AT&T语法对我来说看起来像是一个难以理解的混乱,尤其是解除引用和偏移的可怕符号1)
要理解这一点,请在函数prolog之后的x86上的cdecl函数调用中保留这个堆栈通常看起来的方便图表:
并记住括号中的表达式是指针解除引用操作.
从本质上讲,这是一个(非常天真)的翻译
int multiply(int a, int b) {
// \ \ &b == ebp+12
// \ &a == ebp+8
int c = a*b;
// \ \ multiplication performed in eax
// \ &c == ebp-4
return c;
// \ return value left in eax
}
Run Code Online (Sandbox Code Playgroud)
(使用cdecl调用约定,调用者有责任从堆栈中清除参数)
可能这是由禁用了优化的编译器生成的.更紧凑的版本是:
mov eax, [esp+4]
imul eax, [esp+8]
ret
Run Code Online (Sandbox Code Playgroud)
(因为一切都可以在没有局部变量的情况下完成,甚至不需要设置堆栈帧)
编辑
刚刚检查过,你的代码与gcc产生的代码完全匹配-O0,而我的代码几乎与生成的代码相同-O3.
记录:当你看到
displacement(%register, %offset_register, multiplier)
Run Code Online (Sandbox Code Playgroud)
(其他每个组件%register都是可选的)它实际上意味着AT&T语法
[register + displacement + offset_register*multiplier]
Run Code Online (Sandbox Code Playgroud)
括号的意思是"取值存储在这里".
此外,几乎所有参数都以AT&T语法交换(在Intel语法中,目标操作数在左侧,即mov读取类似于赋值 - mov ebp, esp=> ebp = esp).