关于AT&T 汇编:64 位之于32 位的变化

换了64 位的系统,然后最近用了一下as,发现调用C 库直接不行了。

查了下貌似64 位的AT&T 汇编和32 位的已经有很大的不同。

下面是一些主要的不同之处,如果不怕麻烦可以自己看看文档System V Application Binary Interface AMD64 Architecture Processor Supplement。“这也是汇编语言不可移植的明证。”  ——御坂0x4e27 如此说道。


1. 函数调用不再采用单纯压栈的方式:

下面的内容摘自WikiPedia

Parameters in registers:RDI, RSI, RDX, RCX, R8, R9, XMM0–7

Parameter order on stack:RTL (C)

Stack cleanup by:Caller(调用者清理)

Notes:Stack aligned on 16 bytes boundary.Red zone below stack.

下面的内容摘自WikiPedia

The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point arguments.

additional arguments are passed on the stack and the return value is stored in RAX.


2. 系统调用的改变:

首先,int 0x80 指令被syscall 取代。

再者,系统调用编号已经改变,把下面的代码加入你的~/.bashrc

alias igrepsyscall_32='cat /usr/include/asm/unistd_32.h | grep -e '
alias igrepsyscall_64='cat /usr/include/asm/unistd_64.h | grep -e '
例如最常用的write 系统调用,32 位下是4,64 位下是1:

最后一点:系统调用的参数传递不再使用32 位下的寄存器,而是和函数调用使用的寄存器一致。

(摘自WikiPedia

The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point arguments.

For system calls, R10 is used instead of RCX.


下面是一段很简短的代码,演示了这些不同:

# only for as x86_64

.section    .data
strFormat:
    .asciz "%s\n"
strUseLibc:
    .asciz "Hi, If you see me, you called c lib :)"
strUseSyscall:
    .asciz "And if you see me, you called syscall.\n"
endOfStrUseSyscall:

.section    .text
.globl  _start
_start:
    # 函数调用的传参已经不再单纯使用压栈的方式
    movq    $strFormat, %rdi
    movq    $strUseLibc, %rsi
    call    printf

    # 系统调用的寄存器已经改变,int 0x80 也被syscall 替代
    movq    $1, %rdi
    movq    $strUseSyscall, %rsi
    movq    $(endOfStrUseSyscall-strUseSyscall), %rdx
    movq    $1, %rax
    syscall

    # 另外系统调用的编号也不同了
    movq    $127, %rdi      # 故意返回一个非0 值
    movq    $60, %rax
    syscall
 


不同大约就是这样,祝你愉快 :D


当然你仍然使用64 位开发环境来写32 位程序,只需要给编译器和链接器传递对应的参数,例如:

# as --32 -o file.o file.s
# ld -m elf_i386 --oformat elf32-i386 -o file file.o
另外--oformat 不加貌似也可以正常工作。



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值