曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7456|回复: 0
打印 上一主题 下一主题

汇编函数的定义

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2010-8-18 13:20:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在源代码文件中,汇编函数里的指令必须和主程序的其余指令分开。为了在 GNU 汇编器中定义函数,必须在程序中把函数名称声明为标签。为汇编器声明函数名称,可以使用 .type 命令:
.type func1, @function
func1:
上面定义告诉汇编器,函数从 func1 标签处开始。在函数中,可以访问寄存器和内存位置,可以使用专门特性,如 FPU、MMX 和 SSE。
函数的结束由 RET 指令定义。当执行 RET 时,程序返回到主程序,返回的位置紧跟在调用函数的 CALL 指令后面的指令。
在一般情况下,有两种参参数传递情况最为常见:
      把结果存放在一个或者多个寄存器中
      把结果存放在全局变量内存位置中
函数测试程序:
.section .data
precision:
     .byte 0x7f, 0x00

.section .bss
     .lcomm value, 4
     .lcomm result, 4
.section .text
.global _start

_start:
     nop
     finit
     fldcw precision  #设置FPU为单精度

     movl $10, %ebx
     call area

     movl $2, %ebx
     call area

     movl $1, %eax
     movl $0, %ebx
     int $0x80

.type area, @function   #求圆面积函数
area:
     fldpi    #pi值加载到FPU寄存器堆栈
     imull %ebx, %ebx  #半径的平方
     movl %ebx, value   
     filds value       #半径平方值加载到FPU堆栈顶部
     fmulp %st(0), %st(1)  #圆面积存于st(1),然后弹st(0)出堆栈,最终结果值存于st(0)中
     fstps result   #结果出栈后存入全局变量result中
     movl result, %eax  #将结果值放入EAX
     ret   #函数返回
三点说明:
1. 函数的放置位置
函数代码可以放在主程序的代码后面,也可以放在前面。在连接源代码时,连接器查找标签为 _start 的代码段作为要执行的第一条指令。可以把任意数量的函数代码放在 _start 之前。

2. 使用寄存器
上面程序中的 area 函数在处理过程中只使用了单一输出寄存器,但更加复杂的函数不会这么做。函数经常使用寄存器处理数据,不能保证函数完成时寄存器状态和函数被调用之前的状态相同。在函数中使用寄存器,要保证在函数返回后寄存器的状态也要得到恢复。所以在调用函数之前,可以使用 PUSH 指令单独地保存特定寄存器,也可以使用 PUSHA 指令同时保存所有寄存器。类似的,可以使用 POP 指令单独地恢复特定寄存器,也可以使用 POPA 指令同时恢复所有寄存器。

3. 全局变量
上面程序中,result 是个全局变量,在主程序里也可以访问它。但使用全局变量来传递参数和返回结果不是常见的程序设计方法,即使在 C 和 C++ 程序设计中也不是。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-4-29 06:20 , Processed in 0.060366 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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