Assembly 简单的汇编级程序会产生分段错误

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标签上重新调用

我想知道是否有人能帮助我理解为什么我的汇编程序给了我一个分段错误。(别担心,这是一个相当短的程序。)

它应该将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
标签上重新调用
,因为它不是
调用
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