[轉]64位gcc編譯32位匯編


本文轉載自:http://www.cnblogs.com/chobits/p/4264724.html

 

由於使用as和ld來編譯鏈接匯編程序,在使用C庫的時候比較麻煩,需要輸入比較多的指令,所以使用gcc進行編譯鏈接。由於書中內容是32位匯編程序,但是機器使用的是64位操作系統,自帶的gcc也是64位的,導致編譯生成的程序,一運行就會Segment Fault。經過查詢之后,發現是調用printf函數的時候,總是報錯,查詢之后發現是32位匯編和64位匯編在調用C庫的時候,32位使用pushl指令來壓棧傳遞參數,而64位匯編是使用通用寄存器來傳遞參數的。

  32匯編的代碼是:

復制代碼
 1 .code32
 2 .section .data
 3 output:
 4     .asciz "The processor Vendor ID is '%s'\n"
 5 
 6 .section .bss
 7     .lcomm buffer, 12
 8 
 9 .section .text
10 .globl main
11 main:
12     movl $0, %eax
13     cpuid
14 
15     movl $buffer, %edi
16     movl %ebx, (%edi)
17     movl %edx, 4(%edi)
18     movl %ecx, 8(%edi)
19 
20     pushl $buffer
21     pushl $output
22     call printf
23     addl $8, %esp
24 
25     pushl $0
26     call exit
復制代碼

 

  64位匯編需要這么寫:

復制代碼
.section .data
output:
 .asciz "The Processor Vendor ID is '%s'\n"
.section .bss
 .lcomm buffer, 12
.section .text
.globl main
main:
 movq $0, %rax
 cpuid
 movq $buffer, %rdi
 movq %rbx, (%rdi)
 movq %rdx, 4(%rdi)
 movq %rcx, 8(%rdi)
 movq $buffer, %rsi #1st parameter
 movq $output, %rdi #2nd parameter
 movq $0, %rax
 call printf
 addq $8, %rsp
 pushq $0
 call exit
復制代碼

  從兩種代碼中可以看出來,64位匯編首先mov使用的是movq,32位是movl,而且64位調用printf使用的通用寄存器傳遞參數,而32位使用的是pushl壓棧來傳遞參數的。

  但是64位gcc編譯生成的32位匯編程序運行就會報錯,所以需要讓gcc兼容32位匯編,首先在編譯的時候加上-m32參數選項,但是光這樣,編譯的時候會報錯,還需要下載gcc的32位兼容包,在ubuntu下使用的指令

  sudo apt-get install g++-multilib libc6-dev-i386,參考http://www.cyberciti.biz/tips/compile-32bit-application-using-gcc-64-bit-linux.html

  然后再使用指令gcc -g -m32 -o cpuid2 cpuid2.s編譯生成,就可以正常運行了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM