我在 Linux x86_64 上使用 YASM。
我正在关注 Internet 上的汇编语言介绍。我已经介绍了基本数据类型。现在我正在研究循环构造。很好,但我的第一次尝试失败了。此代码段错误围绕 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
。
有人对此有很好的解释吗?
最佳答案
嗯,你正在使用x86
中断调用
int 0x80
应该改成
syscall
对于 x86_64
。在使用 64 位
寄存器时,您依赖于 x86
兼容性。正如 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
)
关于linux - 为什么在使用 cmp 指令时会出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30246258/