gas汇编(Gnu Assembly)64位系统编译32位汇编程序

在《汇编语言程序设计》这本书中,第4章有一个调用C语言printf函数打印的程序。在64位的操作系统上是不能够按书上的方法编译这段程序的。代码如下

#打印CPUID
.section .data
#初始化代码
output:
    #12位CPUID
    .asciz "The processor Venfor ID is '%s'\n"
.section .bss
#未初始化代码
    .lcomm buffer,12
.section .text
.globl main
main:
    movl $0,%eax#this is an instruction
    cpuid#move the value output to edi
    movl $buffer,%edi
    movl %ebx,(%edi)
    movl %edx,4(%edi)
    movl %ecx,8(%edi)
    pushl $buffer
    pushl $output
    call printf
    addl $8,%esp
    pushl $0
    call exit

使用下面的代码编译就可以成功运行。
下面这种方式时候在调用C语言代码的时候使用。

as -32 -gstabs -o print_cpuid_c.o print_cpuid_c.s 
gcc -m32 -g -o print_cpuid_c print_cpuid_c.s -fno-pie -no-pie  
./print_cpuid_c

-gtabs 表示生成STABS(Symbol Table String),功能就是生成的二进制会多出额外信息可以方便调试。
在使用gcc而不是ld做链接的情况下,_start要改为main,因为gcc只认main。
-g 这行必须加不然不能调试,报
Single stepping until exit from function printf,
which has no line number information.
-fno-pie -no-pie 不加也会报错。
/usr/bin/ld: /tmp/ccbS29lq.o: warning: relocation in read-only section `.text’
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE

但是这个编译存在一些小问题:
1.必须使用main而不能使用_start
2.-o后面跟的可执行程序名 必须和.s文件前面部分的名字一样。这个非常的奇怪。导致gdbinit文件失效。
因为gdbinit文件里面有一个file命令,必须指定程序名字,通常情况下,这个名字是写成固定的例如run.exe或者program等名字,但是因为第2个问题的原因,这个名字就不能固定了。导致gdbinit基本就没法用了。
所以万不得已,不要用gcc这种方式,还是ld的方式比较好。
后面再添加ld的方法…

还有一个问题是每次都必须要编译成32位。因为默认是64位的,在gdb的时候,寄存器什么的都会不一样。这样就不能和书本统一了。

这种方式适合一般情况下:

as -32 -gstabs -o movtest1.o movtest1.s
ld -m elf_i386 -o program movtest1.o

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值