我想知道这是否允许组装
movl (%edx) (%eax)
Run Code Online (Sandbox Code Playgroud)
我猜想它会访问第一个操作数的内存,然后放入第二个操作数的内存,类似* a = * b,但是我没有看到任何处理此类的示例,因此我猜想它是不允许的。另外,有人告诉我这是不允许的
leal %esi (%edi)
Run Code Online (Sandbox Code Playgroud)
这是为什么?最后,还有其他类似的功能我不应该被禁止。
说明除非我们在将立即数添加到存储在内存地址的值时指定大小运算符(例如byte或dword),否则NASM 将返回错误消息。
section .data ; Section containing initialized data
memory_address: db "PIPPACHIP"
section .text ; Section containing code
global _start ; Linker needs this to find the entry point!
_start:
23 mov ebx, memory_address
24 add [ebx], 32
Run Code Online (Sandbox Code Playgroud)
………………………………………………………………………………………………………………………………………………………… ......
24: error: operation size not specified.
Run Code Online (Sandbox Code Playgroud)
公平的公平。
我很好奇为什么会这样。由于以下两段代码将产生相同的结果。
add byte [ebx], 32
或者
add dword [ebx], 32
那么它有什么区别呢?(除了对为什么在这种情况下使用 dword 没有多大意义之外)。仅仅是因为“NASM 这么说”吗?还是这里有一些我缺少的逻辑?
例如,如果汇编程序可以从寄存器名称解密操作数大小,add [ebx], eax那么为什么不对立即值执行相同的操作,即继续并预先计算立即值的大小。
什么要求意味着在将立即值添加到内存地址处的值时需要指定大小运算符?
NASM 版本 2.11.08 架构 x86
我刚开始在大学学习汇编(x86,NASM),我真的很困惑它是如何工作的。在我对此提出的许多问题中,这一直困扰着我。
我什么时候需要指定操作数的大小?有规律吗?例如:
segment data use32 class=data
a db 10
b dw 40
segment code use32 class=code
start:
mov AX, [b]
div BYTE [a]
Run Code Online (Sandbox Code Playgroud)
这里我们将操作div码中操作数的大小指定为BYTE。如果我删除那BYTE部分,我会得到一个错误,所以我们需要指定它。
segment data use32 class=data
a db 10
b dw 40
segment code use32 class=code
start:
mov AH, 2
mul AH
Run Code Online (Sandbox Code Playgroud)
在这里,我们不需要指定操作数的大小2。它只是有效。
那么我什么时候必须指定尺寸?是不是很简单:当我在内存中声明了一个变量时,指定它的大小?考虑到上面给出的例子,我倾向于这么认为,但通过我对 Assembly 的短暂体验,我发现它往往违背我关于事情应该如何运作的逻辑。
另外,在告诉我什么时候需要指定尺寸之后,你能告诉我为什么我们需要这样做吗?当我们需要这样做时,我们为什么需要这样做?我的意思是,我们已经声明了变量,所以变量的类型应该对程序可见,不是吗?为什么我们需要指定大小,否则我们会得到一个错误?