如何在不调用的情况下执行子程序?
How subroutine gets executed without being called?
我是汇编的新手 (x86_64),偶然发现了一个教程,该教程提供了一个简单的程序来打印未定义长度的字符串。程序如下:
section .data
text db "Hello, World!",10,0
section .text
global _start
_start:
mov rax, text
call _print
mov rax, 60
mov rdi, 0
syscall
_print:
push rax
mov rbx, 0
_printLoop:
inc rax
inc rbx
mov cl, [rax]
cmp cl, 0
jne _printLoop
mov rax, 1
mov rdi, 1
pop rsi
mov rdx, rbx
syscall
ret
我理解它的逻辑,除了一件事,_printLoop
子例程是如何在根本没有被调用的情况下执行的?是不是因为 _print
没有 ret
语句而失败?标签不是封装吗?提前感谢您的任何解释!
正如 @ped7g 指出的那样,执行该例程的原因是因为它从打印例程中掉下来了。
在汇编中,call
指令将 return 地址保存到内存(在堆栈上)并且 不会 弹出它(即 return 到所说的点),直到遇到 ret
语句。执行总是继续到下一条指令,除非有某种跳转(call/ret/jmp),不管标签如何。
至于标签,它们只是"nicknames"某些内存位置,以便程序员更容易编写汇编代码。无需记住一个十六进制地址并跳转到它,您可以只使用标签来引用它。这是他们唯一的功能;此连接(十六进制地址和标签之间)由汇编器(以及当前文件外部标签的链接器,或用于绝对引用而不是相对引用)完成。
我是汇编的新手 (x86_64),偶然发现了一个教程,该教程提供了一个简单的程序来打印未定义长度的字符串。程序如下:
section .data
text db "Hello, World!",10,0
section .text
global _start
_start:
mov rax, text
call _print
mov rax, 60
mov rdi, 0
syscall
_print:
push rax
mov rbx, 0
_printLoop:
inc rax
inc rbx
mov cl, [rax]
cmp cl, 0
jne _printLoop
mov rax, 1
mov rdi, 1
pop rsi
mov rdx, rbx
syscall
ret
我理解它的逻辑,除了一件事,_printLoop
子例程是如何在根本没有被调用的情况下执行的?是不是因为 _print
没有 ret
语句而失败?标签不是封装吗?提前感谢您的任何解释!
正如 @ped7g 指出的那样,执行该例程的原因是因为它从打印例程中掉下来了。
在汇编中,call
指令将 return 地址保存到内存(在堆栈上)并且 不会 弹出它(即 return 到所说的点),直到遇到 ret
语句。执行总是继续到下一条指令,除非有某种跳转(call/ret/jmp),不管标签如何。
至于标签,它们只是"nicknames"某些内存位置,以便程序员更容易编写汇编代码。无需记住一个十六进制地址并跳转到它,您可以只使用标签来引用它。这是他们唯一的功能;此连接(十六进制地址和标签之间)由汇编器(以及当前文件外部标签的链接器,或用于绝对引用而不是相对引用)完成。