Assembly 简单的汇编级程序会产生分段错误
我想知道是否有人能帮助我理解为什么我的汇编程序给了我一个分段错误。(别担心,这是一个相当短的程序。) 它应该将a和b的值相加,然后在程序终止时作为最后一个退出代码返回,对吗?所以Assembly 简单的汇编级程序会产生分段错误,assembly,64-bit,nasm,Assembly,64 Bit,Nasm,我想知道是否有人能帮助我理解为什么我的汇编程序给了我一个分段错误。(别担心,这是一个相当短的程序。) 它应该将a和b的值相加,然后在程序终止时作为最后一个退出代码返回,对吗?所以echo$?应该打印4271?由于异或,它应该打印0 但是是的,编译时使用:nasm-f elf64-l main.lst main.asm-o main.o&&ld main.o-o main.exec 然后运行:/main.exec&&echo$? 我们将一如既往地感谢您的帮助。您不能从\u start标签上重新调用
echo$?
应该打印4271
?由于异或,它应该打印0
但是是的,编译时使用:nasm-f elf64-l main.lst main.asm-o main.o&&ld main.o-o main.exec
然后运行:/main.exec&&echo$?
我们将一如既往地感谢您的帮助。您不能从
\u start
标签上重新调用,因为它不是调用
ed。
试试看。(未经测试!)您不能从\u start
标签进行ret
,因为它不是call
ed。
试试看。(未经测试!)哦,太棒了,现在很明显了。顺便说一句,为什么要将rad迁移到rdi?PS:我在linux上,所以我想我需要int 0x80而不是mov al,60No,rax
的高位是0,所以mov al,60
使rax
60(系统退出)rdi
是第一个(唯一)参数。64位Linux使用syscall
而不是int0x80
int0x80
仍将在64位代码中工作,使用旧的32位系统调用号(我听说)。那么syscall是一种更老的方法吗?我正在看一本(实际上不是特别好)介绍64位Linux asm的书。那里使用的约定是int 0x80。我认为syscall
将是更新的方法int0x80
是较旧的方法。哦,糟糕,现在很明显,为什么要将rad移到rdi btw?PS:我在linux上,所以我想我需要int 0x80而不是mov al,60No,rax
的高位是0,所以mov al,60
使rax
60(系统退出)rdi
是第一个(唯一)参数。64位Linux使用syscall
而不是int0x80
int0x80
仍将在64位代码中工作,使用旧的32位系统调用号(我听说)。那么syscall是一种更老的方法吗?我正在看一本(实际上不是特别好)介绍64位Linux asm的书。那里使用的约定是int 0x80。我认为syscall
将是更新的方法int 0x80
是较旧的方法。
segment .data
a dq 175
b dq 4096
segment .text
global _start
_start:
mov rax, [a] ; move *a into rax
add rax, [b] ; add *b to rax
xor rax, rax ; set to zero
ret ; return
segment .data
a dq 175
b dq 4096
segment .text
global _start
_start:
mov rax, [a] ; move *a into rax
add rax, [b] ; add *b to rax
xor rax, rax ; set to zero
mov rdi, rax
mov al, 60 ; sys_exit
syscall