Assembly x64程序集GNU语法,循环如何返回

Assembly x64程序集GNU语法,循环如何返回,assembly,x86-64,att,Assembly,X86 64,Att,这是一个汇编程序x64 GNU语法的程序 .global main .text main: xor %rax, %rax mov %rax, %rbx .L1: add $1, %rbx add %rbx, %rax cmp $10, %rbx jne .L1 ret 我手动进行了循环,发现当循环终止时,返回函数(ret),rbx=10,rax=45,但我不明白它们是如何返回到主函数的,当它们返回主函数时会

这是一个汇编程序x64 GNU语法的程序

    .global main
    .text
main: 
    xor  %rax, %rax
    mov  %rax, %rbx

.L1:
    add  $1, %rbx
    add  %rbx, %rax
    cmp  $10, %rbx
    jne  .L1
    ret

我手动进行了循环,发现当循环终止时,返回函数(ret),rbx=10,rax=45,但我不明白它们是如何返回到主函数的,当它们返回主函数时会发生什么

ret指令不会返回主指令,但它会从主指令返回,以开始终止程序。您编写的循环不是一个函数,您只是跳回代码的前一行,不需要用ret指令终止它。尽管你需要ret来终止你的程序


要回答关于你的价值观走向何方的问题,它们不会走向任何地方。如果我们把事情简化一点,不考虑上下文切换,你的值仍然会被物理地存储在寄存器中,直到函数调用中的某个代码或其他代码重用它们。要了解在函数调用时如何处理寄存器以及如何向函数传递参数,请查看调用约定。

ret指令不会返回到主指令,而是从主指令返回,以开始终止程序。您编写的循环不是一个函数,您只是跳回代码的前一行,不需要用ret指令终止它。尽管你需要ret来终止你的程序


要回答关于你的价值观走向何方的问题,它们不会走向任何地方。如果我们把事情简化一点,不考虑上下文切换,你的值仍然会被物理地存储在寄存器中,直到函数调用中的某个代码或其他代码重用它们。要了解在函数调用时如何处理寄存器以及如何向函数传递参数,请查看调用约定。

x86 ISA本身没有返回值的概念。返回值是如何返回的(如果有的话)只是一个惯例,尽管通常情况下,
rax
中的任何内容都被用作返回值。所以基本上,最后rax=45和rbx=10就是这样,对吗?是的。还要注意,标准调用约定说,
rbx
是被调用方保存的寄存器,因此您应该真正保留其值。要清除rax,请使用
xor%eax,%eax
@Dan请阅读上面的链接,它确实清除了整个64位寄存器。x86 ISA本身没有返回值的概念。返回值是如何返回的(如果有的话)只是一个惯例,尽管通常情况下,
rax
中的任何内容都被用作返回值。所以基本上,最后rax=45和rbx=10就是这样,对吗?是的。还要注意,标准调用约定说,
rbx
是被调用方保存的寄存器,因此您应该真正保留其值。要清除rax,请使用
xor%eax,%eax
@Dan请阅读上面的链接,它确实清除了整个64位寄存器。非常感谢。我还有一个问题,64位CPU支持的常见寻址模式是什么?不客气!关于寻址模式,有比我在评论中可能写的更好的文本可供阅读,因此我推荐我从中学习的文本。乔纳森·巴特利特(Jonathan Bartlett)的《从头开始编程》是一本非常好的入门书,它是免费的,它涵盖了32位Linux编程,但在寻址模式方面,它并不重要。阅读“寻址模式”一节可以澄清这个概念。@Dan:See(答案使用NASM语法,但AT&T语法可以表示所有相同的寻址模式。)x86-64中的新寻址模式是RIP相对的,对于位置无关的代码非常有用。顺便说一句,有关指南/文档(包括PGU手册)的更多链接,请参阅。谢谢!,我还有一个问题,64位CPU支持的常见寻址模式是什么?不客气!关于寻址模式,有比我在评论中可能写的更好的文本可供阅读,因此我推荐我从中学习的文本。乔纳森·巴特利特(Jonathan Bartlett)的《从头开始编程》是一本非常好的入门书,它是免费的,它涵盖了32位Linux编程,但在寻址模式方面,它并不重要。阅读“寻址模式”一节可以澄清这个概念。@Dan:See(答案使用NASM语法,但AT&T语法可以表示所有相同的寻址模式。)x86-64中的新寻址模式是RIP相对的,对于位置无关的代码非常有用。顺便说一句,有关指南/文档(包括PGU手册)的更多链接,请参阅。