【发布时间】:2016-08-23 07:29:34
【问题描述】:
我对汇编程序级别的指针有很大的误解。我知道要获取指针(变量)的地址,您可以使用
MOV EAX, variable
or
LEA EAX, variable
我也知道 MOV 有许多不同的 OP 代码,但我感兴趣的是 MOV register, address。
问题是......它如何知道变量位于哪个地址?汇编器是否已经在可执行文件中生成了MOV EAX, address_of_variable 或者指令是MOV EAX, ... 并且它找到了该值然后获取它的地址。但是它怎么知道如何在内存中搜索那个值然后返回地址(假设地址每次都改变)。
如果这是一个愚蠢的问题,请原谅我,但我不明白它是如何做到的。
【问题讨论】:
-
MOV EAX, variable在 NASM 语法中组装成mov eax, imm32操作码。汇编器留下 4 个字节的零作为数据,链接器用该符号引用的绝对地址填充它(仅在链接时才知道)。从来没有任何“搜索记忆”。在 MASM 语法中,mov eax, variable是来自该变量的加载(但同样,绝对地址由链接器填充,作为寻址模式的 disp32 而不是 imm32)。在 NASM 语法中,lea eax, variable是语法错误;也许你在想lea eax, [variable]? -
所以当我运行程序时链接器运行?当我执行程序时,链接器在我的代码之前运行?
-
链接器是从汇编器输出创建可执行文件的东西。 .asm -> .o 是汇编程序。
.o->a.out(或.exe)是链接器。 -
链接时怎么知道?链接器是否将显式内存地址放入可执行文件?如果是 .so 或 .dll ,地址每次都会改变?我知道它使用虚拟地址,并且每个程序都相同,但我仍然不明白.. :(
-
它在链接时是已知的,因为可执行文件不是位置独立的。 (它们被加载到一个固定的地址,
mov eax, imm32地址利用了这一点)。您不能在共享库或其他需要 PIC(位置独立代码)的地方使用mov eax, var。我将写下这些 cmets 作为答案。我应该使用什么操作系统作为示例?哪个汇编器:NASM 风格还是 MASM 风格? 32 位还是 64 位(RIP 相关的 LEA 解决了 PIC 问题)?
标签: pointers assembly x86 memory-address