NASM 创建函数局部符号的方法以及它们在递归情况下的行为方式

问题描述 投票:0回答:1

根据我所了解到的,我很可能是错的,要在 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”等本地符号时,它们是否会访问相同的内存空间?

我想第一种方法不会有递归问题,因为每次迭代都会在堆栈上为其自己的变量保留空间。

assembly x86 nasm
1个回答
0
投票

.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 只知道如何编码指令,它不关心它们将如何执行。

循环和递归是运行时的事情,在组装和链接完成后很长时间内发生。

© www.soinside.com 2019 - 2024. All rights reserved.