QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1598|回复: 2

gas汇编与C的相互转换问题--函数的入/出口参数?

[复制链接]
发表于 2004-8-2 13:07:12 | 显示全部楼层 |阅读模式
/* 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

请熟悉的大侠给讲解,小弟先谢谢了!
发表于 2004-8-8 13:10:51 | 显示全部楼层
[code:1] subl $4, %esp [/code:1]
一般来说,esp是用来分配函数内部空间的,它这句就是分配了一个4个字节的临时空间,在本程序里是用来存放把4字节的eax,edx转换为2字节的word型用的,即这两句:
[code:1]
movw %ax, -2(%ebp)
movw %dx, -4(%ebp)
[/code:1]

因为当用call调用一个过程或者函数的时候在链接时做了一次压栈动作,把eip压栈,
当你调用ret返回的时候,系统会做一次出栈的操作,即popl,来恢复eip,这样
程序才继续执行。
所以,这样算来,pushl %eip, 又,函数开始时pushl %ebp,而且 %ebp 在函数开始时
movl %esp, %ebp了,所以
第一个参数才是在8(%ebp) 了

leave语句其实和下面两句干了一样的活,是等价的
[code:1]
movl %ebp, %esp
popl  %ebp
[/code:1]

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

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

使用道具 举报

 楼主| 发表于 2004-8-14 12:35:50 | 显示全部楼层

Thanks!

[quote:cb1ae0ab02="yunfan"][code:1] subl $4, %esp [/code:1]
一般来说,esp是用来分配函数内部空间的,它这句就是分配了一个4个字节的临时空间,在本程序里是用来存放把4字节的eax,edx转换为2字节的word型用的,即这两句:
[code:1]
movw %ax, -2(%ebp)
movw %dx, -4(%ebp)
[/code:1]

因为当用call调用一个过程或者函数的时候在链接时做了一次压栈动作,把eip压栈,
当你调用ret返回的时候,系统会做一次出栈的操作,即popl,来恢复eip,这样
程序才继续执行。
所以,这样算来,pushl %eip, 又,函数开始时pushl %ebp,而且 %ebp 在函数开始时
movl %esp, %ebp了,所以
第一个参数才是在8(%ebp) 了

leave语句其实和下面两句干了一样的活,是等价的
[code:1]
movl %ebp, %esp
popl  %ebp
[/code:1]

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

呵呵,不知我说明白了没有?[/quote]

非常明白,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-16 06:45 , Processed in 0.039537 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表