当然MOV
“移动”(实际上是副本)某些东西,但是怎么样?它是否将来自源的实际值放入目的地或放置某种地址。
当我在杰夫·丹特曼(Jeff Duntemann)的介绍性装配书中看到他正在使用像这样的中断80h的Linux时,这个问题出现了:
mov eax,4 ; Specify sys_write call
mov ebx,1 ; Specify File Descriptor 1: Standard output
mov ecx,Buff ; Pass address of the character to write
mov edx,1 ; Pass number of chars to write
int 80h ; Call sys_write
在我开始阅读之前,我几乎没有使用过TASM练习,但知道LEA的说法。所以当我看到时:
mov ecx,Buff ; Pass address of the character to write
由于我使用LEA
(加载有效地址)或OFFSET将地址放入寄存器并且他正在使用MOV
,所以它让我感到震惊。
这两种形式都是正确的吗?不过,他正在使用NASM,因为汇编程序也是如此?我现在很困惑,因为我习惯看到MOV
将值设置为地址。
答案 0 :(得分:2)
MOV
(移动)指令在存储器和寄存器之间或寄存器之间传输数据。 MOV
指令执行基本的加载数据并在存储器和处理器的寄存器之间存储数据操作以及寄存器之间的数据移动操作。MOV
指令不能将数据从一个存储单元移动到另一个存储单元或从一个段寄存器移动到
另一个段登记册。使用MOVS
(字符串移动)指令执行内存到内存的移动。
LEA
(加载有效地址)指令计算源操作数的内存中的有效地址(段内的偏移量)并将其置于通用寄存器中。该指令可以解释任何处理器
寻址模式,可以执行任何可能需要的索引或缩放。
Intel 64和IA-32架构软件开发人员手册
它作为3-operand non-destructive add非常有用,例如ecx = eax + edx*4 - 15
NASM 通过为内存引用提供更简单的语法来避免这种不良情况。规则很简单,任何对内存位置内容的访问都需要围绕地址的方括号,并且对变量地址的任何访问都不需要。因此,mov ax, foo
形式的指令将始终引用编译时常量,无论它是EQU
还是变量的地址;要访问变量栏的内容,您必须编写mov ax, [bar]
代码。这也意味着 NASM 不需要 MASM的 OFFSET
关键字,因为 MASM 代码mov ax, offset bar
意味着与 NASM的 mov ax,bar
相同。
Nasm文档
从上面的所有内容中,您可能会发现有不同的方法可以在asm中获取变量的地址,这些方式在不同的汇编语言中可能会有所不同。要找到问题的答案,最好查看文档(汇编语言通常都有详细记录)。
你应该永远记住,在编程中总有几种方法可以解决一个特定的问题。