[英]Differences between MOV, LEA and OFFSET
当然, MOV
“移动”(实际上是复制)某些东西,但是如何? 它是将来自源的实际值放入目的地还是放入某种地址。
当我在杰夫·邓特曼(Jeff Duntemann)的介绍性汇编书中看到他正在使用Linux的中断80h时,这个问题浮现出来:
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
这让我MOV
。
两种形式都正确吗? 但是,他正在使用NASM,是因为汇编程序吗? 我现在很困惑,因为我习惯于看MOV
将值放在地址之外。
MOV
(移动)指令在存储器和寄存器之间或寄存器之间传输数据。 MOV
指令执行基本的加载数据并在内存和处理器的寄存器之间存储数据操作以及在寄存器之间的数据移动操作MOV
指令不能将数据从一个存储位置移动到另一个或从一个段寄存器移动到另一个段寄存器。 内存到内存的移动是通过MOVS
(字符串移动)指令执行的。
LEA
(加载有效地址)指令计算源操作数的内存(段中的偏移量)中的有效地址,并将其放置在通用寄存器中。 该指令可以解释任何处理器的寻址模式,并可以执行可能需要的任何索引或缩放。
英特尔64和IA-32架构软件开发人员手册
作为三操作数无损添加 ,它也非常有用,例如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中获取变量的地址,并且这些方法在不同的汇编语言中可能也将有所不同。 要找到问题的答案,最好检查一下文档(汇编语言通常都记录在案)。
您应该永远记住,在编程中总有几种方法可以解决一个特定的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.