天天看點

第13部分-Linux x86 64位彙編 獨立函數檔案第13部分-Linux x86 64位彙編 獨立函數檔案

第13部分-Linux x86 64位彙編 獨立函數檔案

将各個函數字自包含在自己的檔案中,并且連接配接在一起成為最終産品。

函數的檔案不需要使用_start段。不過需要将函數名字聲明為全局标簽,以便其他程式能夠通路,使用.globl指令來完成。

例如:

.section .text

.type area,&function

.globl area

area:

示例

函數檔案:

檔案為area.s

.section .text
.type area, @function;//定義函數area
.globl area
area:
   push %rbp;//壓棧ebp寄存器
   mov %rsp, %rbp;//将esp指派為ebp
   subq $8, %rsp;//設定rsp網上走,這裡其實沒有實際作用,64位系統中一個壓棧就是8個位元組
   fldpi;//加載π到st0
   filds 16(%rbp) ;//加載ebp+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;//傳回函數
           
      1. 主程式檔案

主程式不包含area函數的任何代碼。

檔案為funcmain.s

.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

           

進行編譯連接配接:

as -g -o area.o area.s

as -g -o funcmain.o funcmain.s

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

繼續閱讀