第12部分-Linux x86 64位汇编 函数C样式传递

第12部分-Linux x86 64位汇编 函数C样式传递

因为输入值和输出值可用的选择很多,这样哪个函数使用哪些寄存器和全局变量,或者哪些寄存器和全局变量传递哪些参数会是程序员的噩梦。

为此需要一个标准,使用某一标准一致地存放输入参数以便函数获取,一致地存放输出值便于主程序获取。

         C把输入值传递给函数的解决方案是使用堆栈。C定义了返回主程序的值是用EAX,浮点用ST(0).

         C样式要求参数存放到堆栈中的顺序和函数的原型中的顺序相反。

.extern printf ;//调用外部的printf函数
.section .data
precision:
   .byte 0x7f, 0x00
resultstr:
   .ascii "Area result is %f.\n"

.section .bss
   .lcomm bresult, 4

.section .text
.globl _start
_start:
   nop
   finit;//FPU初始化
   fldcw precision;//加载FPU控制器
   push $10;//加载10到栈中
   call area;//调用area函数
   addq $8, %rsp;//增加8个字节,即跳过压栈的参数
   movl %eax, bresult;//保存结果到result

   movq bresult,%xmm0;//结果复制到xmm0寄存器
   cvtps2pd %xmm0,%xmm0;//转化单精度为双精度
   movq $resultstr,%rdi
   call printf

   push $2
   call area
   addq $8, %rsp
   movl %eax, bresult
   movq $resultstr,%rdi
   movq bresult,%xmm0
   cvtps2pd %xmm0,%xmm0
   call printf

   push $120
   call area
   addq $8, %rsp
   movl %eax, bresult
   movq $resultstr,%rdi
   movq bresult,%xmm0
   cvtps2pd %xmm0,%xmm0
   call printf

   mov $60,%rax
   syscall

.type area, @function;//定义函数area
area:
   push %rbp;//压栈rbp寄存器
   mov %rsp, %rbp;//将rsp赋值为rbp
   subq $8, %rsp;//设置rsp网上走,这里其实没有实际作用,64位系统中一个压栈就是8个字节
   fldpi;//加载π到st0
   filds 16(%rbp) ;//加载rbp+8就是调用函数前压栈的参数到st0,π移到st1
   fmul %st(0), %st(0) ;//st0和st0相乘,保存在st0
   fmulp %st(0), %st(1) ;//st0和st1相乘,结果在栈顶st0
   fstps -8(%rbp) ;//保存结果到栈中, 8个字节,也就是挡墙rsp所指的位置。
   movl -8(%rbp), %eax;//最后将结果移动到eax寄存器,是单精度值

   mov %rbp, %rsp;//恢复esp寄存器
   pop %rbp;//恢复ebp寄存器
   ret;//返回函数

as -g -o ccalltest.o ccalltest.s

ld -o ccalltest ccalltest.o -lc -I /lib64/ld-linux-x86-64.so.2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值