在汇编程序中寻址

时间:2010-03-02 15:17:00

标签: assembly nasm addressing

有些东西我无法消化。我正在学习一些汇编程序,现在我正在阅读这一章。我理解用于解除引用的括号的概念,但不知何故,当我看到它的使用时,我只是无法理解它的重点。更确切地说,这是我的困惑开始的地方:

mov al, [L1]

这里我假设L1作为一个示例案例是某种宏,后来代替了机器码中的实际地址,对吗?

所以这个指令的作用是:取消引用al寄存器(因为你几乎不能改变物理地址)并将值改为存储在L1的值。

如果到现在一切正常:

mov [L1], al

这类似地意味着,必须存储一个地址(所以这样做有一点)并且你将它改为内存中的其他地方,对吗?

如果您可以告诉我,如果您没有看到任何错误,请立即行动,这样我就可以继续学习。

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

3 个答案:

答案 0 :(得分:4)

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

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


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

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

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

  mov [L1], al

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

{{1}}

这是否相反。即,具体而言,读取存储在L1中的地址,使用该地址查找存储器中的特定位置,并将AL寄存器的内容存储在那里。


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

答案 1 :(得分:3)

很难回答你的问题,但我会尽力帮忙。

在汇编中,符号只是地址的名称。在汇编源代码中,L1是在别处定义的符号,汇编器将其解析为内存的偏移量。

取消引用(使用[]表示法)时,可以取消引用寄存器(如“mov al,[esi]”)或地址(如“mov al,[L1]”)。两个语句都做同样的事情,唯一的区别是地址来自哪里。

我建议下载Intel CPU Documentation并浏览指令参考。如果您不想被淹没,请从较旧的x86处理器(例如,486或更早版本)开始阅读,该文档并不完全友好,但手头上的内容非常有用。

我不知道NASM的具体细节,15年前我与Turbo Assembler学习了汇编,而且知识今天仍然有用:)

此外,我可以建议您尝试使用Google搜索“x86汇编教程”,您会找到大量可能对您有用的相关文档。

答案 2 :(得分:1)

  哦,还有最后一件事,NASM增加了一个   我的代码下的一堆0xAA55(这个   序列应该结束   程序吧?),为什么会这样呢?   多次?非常感谢你   读到这里..

我很确定这只适用于您创建引导加载程序的情况。这是“引导签名”。假设您将此代码写入软盘(您生产的机器代码也正好是512字节?),当您想要使用此引导加载程序代码启动计算机时,BIOS将查看软盘并确定它是否是实际的引导加载程序。为了做到这一点,它将查看软盘的第一个扇区的最后两个字节,它应该是0xAA55以表示它是可引导的..(同样,如果你启动它也会以同样的方式工作硬盘驱动器,或拇指驱动器,或其他什么。与CD略有不同,因为它们有4096个字节的扇区)

在你的源代码中,就像最后一行类似$(times.. db 0xAA55之类的东西?如果您不打算制作引导加载程序,则可以有效地删除该行。

相关问题