如何在 asm 中使用 MOV?
Posted
技术标签:
【中文标题】如何在 asm 中使用 MOV?【英文标题】:How can I use MOV in asm? 【发布时间】:2021-10-03 21:22:30 【问题描述】:我在写ASM,实在不懂mov
的规则,所以
mov rax, 100 ; it means that the number 100 is in rax?
mov rax, a ; it means that the value of a is in rax? or is the memory direction?
mov rax, [a] ; it means the value of a? or what?
mov [a], rax ; the direction of memori in a change to rax?
mov rax, rbx ; rbx is now rax?
对不起,如果我的问题很愚蠢,但我真的很困惑...... 谢谢
【问题讨论】:
mov rax, a
的含义取决于您使用的是 NASM 还是 MASM 语法。 (该地址的地址或值)。不过,无论哪种方式,这是 Intel 语法,因此目标始终是最左边的操作数,因此您的最后一条评论是错误的。 (或描述 rax = rbx
的措辞不清楚)。但是,任何教程都应该解释这些基础知识,所以你可能应该继续阅读。一些教程链接可以在***.com/tags/x86/info中找到
mov left, right
始终表示left = right
。唯一的问题是 a
与 [a]
的含义取决于汇编程序。 (假设寄存器名称和立即数很明显。)
【参考方案1】:
既然我们有,mov rax, 100
是有效的,我们知道它是 Intel 语法。继续并假设 a 是一个标签而不是一个宏或 equ 导致一个常量:
mov rax, 100 ; Always means put constant 100 in rax
mov rax, a ; Either means put the address of a in rax,
; or put a in rax depending on which assembler.
; For nasm it's always the address of a.
mov rax, [a] ; Always means the 8 byte value stored at a
; for offsets above 2GB, target register must be al, ax, eax, or rax
mov [a], rax ; Put the value of rax in the value stored at a
mov rax, rbx ; Put the value of rbx in rax (no memory access)
mov rax, [rbx] ; Put the value stored where rbx points into rax
为了完整起见,我添加了最后一个。此处不在 [] 操作中进行数学运算。
但是您很少需要加载绝对地址;你通常想要 rip-relative,你通常应该写以下(NASM 语法):
lea rax, [rel a] ; put address of a into rax
mov rax, [rel a] ; put value at a into rax
【讨论】:
x86-64 允许mov r64, imm64
用于任何寄存器。您可能正在考虑使用 64 位绝对地址加载或存储的 mov al/ax/eax/rax, moffs
表单,它只存在于累加器(4 个操作码,而不是 32 个)。 felixcloutier.com/x86/mov.
在 MASM 中,mov rax, a
是负载,a
将使用 RIP 相对寻址模式,因此您可以加载到任何寄存器中。 (在 GAS .intel_syntax noprefix
中,裸 a
是具有普通 [disp32]
寻址模式的内存操作数,可能无法链接;movabs
用于 64 位绝对,[a + rip]
用于 RIP 相对)
但无论如何,在 NASM 中,您基本上不想将mov rax, a
改为get a static address into a register。要么做lea rax, [rel a]
,要么作为已知链接到地址空间的低32位(如Linux上的非PIE)的可执行文件的优化,mov eax, a
。尽管如此,mov rax, a
确实效率低下,Linux 动态链接确实支持在共享对象(如 PIE 可执行文件)中的 64 位绝对值上进行运行时修复(文本重定位)。
我的最后一条评论是关于 NASM,mov rax,a
将地址放入寄存器。 mov eax, a
是 5 个字节的机器码,因此比 lea rax, [rel a]
(7 个字节)更有效地实现相同的结果。我只提到它作为一个例子,说明在 x86-64 中使用带有绝对地址作为立即数的 mov
仍然有意义,因为如果由NASM。请参阅我在您输入时编辑到我之前评论中的链接。
[rel a]
语法特定于 NASM。 GAS 使用[RIP + a]
(How do RIP-relative variable references like "[RIP + _a]" in x86-64 GAS Intel-syntax work?),MASM 不使用任何东西。这就是为什么我没有回答这个没有指定语言的问题,一般只回答 Intel 语法。写一个正确的答案需要比一个不确定mov rax, 100
可能准备好处理的初学者更详细。以上是关于如何在 asm 中使用 MOV?的主要内容,如果未能解决你的问题,请参考以下文章