汇编程序中的寻址

Pyj*_*ong 2 assembly nasm addressing

有件事我无法消化。我正在学习一些汇编程序,现在我正在学习寻址章节。我理解用于解除引用的括号的概念,但不知怎的,当我看到它的用法时,我就是无法理解它的要点。更准确地说,我的困惑是从这里开始的:

mov al, [L1]
Run Code Online (Sandbox Code Playgroud)

在这里,我假设 L1 作为示例,它是某种宏,稍后会替换机器代码中的真实地址,对吗?

所以这条指令的作用是:取消引用al寄存器(因为你几乎无法更改物理地址)并将值更改为存储在的值L1

如果到目前为止一切正常:

mov [L1], al
Run Code Online (Sandbox Code Playgroud)

类比地意味着,一定已经存储了一个地址(因此这样做是有道理的)并且您将其更改为内存中的其他位置,对吗?

如果你能告诉我没关系,如果你没有看到任何错误,请这样做,这将使我可以继续学习。

最后一件事,NASM 在我的代码下添加了一堆0xAA55(这个序列应该结束程序吧?),为什么它出现了这么多次?

mjv*_*mjv 5

L1通常/可能是一个标签与内存中的一个特定地址相关联。程序员为了方便起见定义了各种标签,这些标签用于象征性地表示内存中的特定位置(L1 是一个糟糕的名称;标签通常指示该位置的基本用途:例如,PingCounter、ErrorMessage、Login等)。

1 字节静态存储的标签是 C 编译器char L1;在全局范围内实现的方式。


在NASM语法中,mov edi, L1将汇编为mov eax, imm32的形式mov,即标签地址将成为机器码中的32位立即数。(汇编器不知道最终的数值,但链接器知道。)请注意,在 MASM 语法中,这将是一个负载,您需要mov edi, OFFSET L1立即获取标签地址。

mov al, [L1]会汇编成不同的指令,并将机器代码中嵌入的 32 位地址作为要取消引用的地址。该指令从地址 L1 加载 1 个字节,并将其放入 AL 中。

在汇编语言中,这种间接寻址模式通过将给定指令的源操作数或目标操作数括在方括号中来表示。(但不能两者兼而有之:x86 每条指令最多只支持一个显式内存操作数。)

mov al, [L1]
Run Code Online (Sandbox Code Playgroud)

使用L1中存储的地址,定位内存中的某个位置,并在该位置读取1个字节(= 8位= AL寄存器的大小),并将其加载到AL寄存器中。

  mov [L1], al
Run Code Online (Sandbox Code Playgroud)

反过来做这个。即,具体来说,读取L1中存储的地址,使用该地址找到存储器中的特定位置并将AL寄存器的内容存储在那里。


如果您了解以下关于 x86 系列中较新处理器的信息不完整且有些过时,那么这本有关 8086 架构的入门知识对于开始使用 x86 系列的汇编语言可能非常有用。
从这个“古老的 CPU”(实际上仍在使用)开始的优点是,基本概念都在那里,不受新的寄存器组、奇特的寻址模式、操作模式和其他概念的阻碍。较新的 CPU 的更大尺寸、功能和模式只是引入了选项的组合爆炸,所有(大多数?)它们都以自己的方式有用,但本质上与启动无关。

  • @stupid_idiot(顺便说一句,你似乎也不是)。不,AL(以及 AH、AX 和所有寄存器名称)不是内存位置,本身没有地址。它们仅引用 CPU 本身内的特定位置。事实上,我的意思是“纠正”你在问题中使用“取消引用寄存器”这一表达方式;对于 AL 没有取消引用,在这种情况下,AL 的寻址模式是“寄存器”。(这可能会令人困惑,因为有时寄存器可用于在内存中生成地址,然后取消引用) (2认同)