我在Linux x86_64上使用YASM。
我正在关注互联网上的汇编语言。我已经介绍了基本数据类型。现在我潜入环路建设。很好,但我的第一次尝试是失败。这段代码围绕cmd
指令的使用进行了细分:
segment .data
a dd 0x01,0x02,0x03,0x04
b dd 0x03,0x03,0x03,0x03
product dd 0x00
segment .text
global _start
_start:
mov rax,0
begin_while:
cmp rax,4
jnl end_while
inc rax
jmp begin_while
end_while:
mov rax,1
xor rbx,rbx
int 0x80
但是当我在_start
标签之后添加这几行时,它会按预期运行。即没有段错误。
push rbp
mov rbp,rsp
sub rsp,16
我正在阅读的这本书经常使用这个结构。不是每次都是。我知道这与调用函数时要遵循的过程有关。我想它可能与libc运行时有关。无论如何,我不明白为什么需要它。到目前为止,我写的所有少数简单程序(不是那么多)我从来没有使用它。就在今天,现在我正在使用jmp
。
有人对此有一个很好的解释吗?
答案 0 :(得分:1)
好吧,您正在使用x86
中断调用
int 0x80
应改为
syscall
代表x86_64
。使用x86
寄存器时,您依赖于64-bit
兼容性。正如Jester所指出的,您的代码将在x86_64
上无错误地编译和运行。 (我已经在AMD64 Linux上确认了这两种方式没有错误)但是,所有平台的实现程度尚不清楚。
在编写x86_64代码时,也应该改变:
mov rax,1
到
mov rax, 0x3c ; 60 decimal
设置正确的x86_64
退出系统调用,而不是依赖x86
兼容性。 (在x86_64中,系统调用号1
为__NR_write 1
,请参阅:/usr/include/asm/unistd_64.h
与/usr/include/asm/unistd_32.h
进行比较)