scmyms 发表于 2004-8-2 13:07:12

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

请熟悉的大侠给讲解,小弟先谢谢了!

yunfan 发表于 2004-8-8 13:10:51

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


即恢复程序现场,因为一开始保存了栈底指针,并且把栈顶指针置为栈顶指针。

呵呵,不知我说明白了没有?

scmyms 发表于 2004-8-14 12:35:50

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]
查看完整版本: gas汇编与C的相互转换问题--函数的入/出口参数?