gas汇编与C的相互转换问题--函数的入/出口参数?
/* C 的过程函数 */u16_t add(u16_t a, u16_t b){
return a+b;
}
/* gas 汇编的代码 */
.text
.align 2
.globl _add
.def _add;
.scl 2;
.type 32;
.endef
_add:
pushl %ebp
movl %esp, %ebp
subl $4, %esp ; 这句有什么作用?不解?!
movl 8(%ebp), %eax ; 为什么第一个参数a在SP+8的位置?!
movl 12(%ebp), %edx
movw %ax, -2(%ebp)
movw %dx, -4(%ebp)
movl -4(%ebp), %eax
addw -2(%ebp), %ax
andl $65535, %eax
leave ; 这句什么意思?
ret
请熟悉的大侠给讲解,小弟先谢谢了! subl $4, %esp
一般来说,esp是用来分配函数内部空间的,它这句就是分配了一个4个字节的临时空间,在本程序里是用来存放把4字节的eax,edx转换为2字节的word型用的,即这两句:
movw %ax, -2(%ebp)
movw %dx, -4(%ebp)
因为当用call调用一个过程或者函数的时候在链接时做了一次压栈动作,把eip压栈,
当你调用ret返回的时候,系统会做一次出栈的操作,即popl,来恢复eip,这样
程序才继续执行。
所以,这样算来,pushl %eip, 又,函数开始时pushl %ebp,而且 %ebp 在函数开始时
movl %esp, %ebp了,所以
第一个参数才是在8(%ebp) 了
leave语句其实和下面两句干了一样的活,是等价的
movl %ebp, %esp
popl%ebp
即恢复程序现场,因为一开始保存了栈底指针,并且把栈顶指针置为栈顶指针。
呵呵,不知我说明白了没有?
Thanks!
subl $4, %esp一般来说,esp是用来分配函数内部空间的,它这句就是分配了一个4个字节的临时空间,在本程序里是用来存放把4字节的eax,edx转换为2字节的word型用的,即这两句:
movw %ax, -2(%ebp)
movw %dx, -4(%ebp)
因为当用call调用一个过程或者函数的时候在链接时做了一次压栈动作,把eip压栈,
当你调用ret返回的时候,系统会做一次出栈的操作,即popl,来恢复eip,这样
程序才继续执行。
所以,这样算来,pushl %eip, 又,函数开始时pushl %ebp,而且 %ebp 在函数开始时
movl %esp, %ebp了,所以
第一个参数才是在8(%ebp) 了
leave语句其实和下面两句干了一样的活,是等价的
movl %ebp, %esp
popl%ebp
即恢复程序现场,因为一开始保存了栈底指针,并且把栈顶指针置为栈顶指针。
呵呵,不知我说明白了没有?
非常明白,谢谢!
页:
[1]