根据我所了解到的,我很可能是错的,要在 NASM 中为函数提供局部变量,我们可以
使用函数基指针的偏移量和堆栈上的空间作为局部变量
在附加部分 .data 或 .bss 中的函数标签后面声明符号,如下所示。
section .text
_FindLongestString:
section .data
.length dd 0
.address dd 0
push ebp
mov ebp, esp
; more instructions
mov esp, ebp
pop ebp
如果我们使用第二种方法,它可以递归吗?或者,当函数的每次迭代引用“.length”等本地符号时,它们是否会访问相同的内存空间?
我想第一种方法不会有递归问题,因为每次迭代都会在堆栈上为其自己的变量保留空间。
.data
中的静态存储仅存在一次,即您放置它的位置。在这种情况下,您将代码放入section .data
中,因为您切换到了它并且没有切换回section .text
。
.length dd 0
就像 C static int length;
- 函数的所有调用都使用相同的 4 个字节的静态存储。
如果您希望在每次调用可重入代码(例如递归和/或线程安全函数)时为局部变量提供唯一的空间,请像 C 编译器那样使用堆栈空间
int length;
。 (没有static
,所以自动存储级。)
NASM 按源顺序处理源文件。不按执行顺序:记住它只是一个汇编器而不是解释器。将
call
或 jmp
指令组装到机器代码中不会使其返回并重新组装旧行。
每个 NASM 源代码行告诉 NASM 将一些字节附加到目标文件的当前部分。这就是组装。例如,
db 0x90
与 nop
完全相同。 NASM 只知道如何编码指令,它不关心它们将如何执行。
循环和递归是运行时的事情,在组装和链接完成后很长时间内发生。