yasm movsx,movsxd操作数2的无效大小 [英] yasm movsx, movsxd invalid size for operand 2
问题描述
我正在尝试使用yasm汇编以下代码.我在"yasm"报告错误错误:操作数2的大小无效"的地方添加了此处"注释.为什么会发生此错误?
I am trying to assemble the code below using yasm. I have put 'here' comments where yasm reports the error "error: invalid size for operand 2". Why is this error happening ?
segment .data
a db 25
b dw 0xffff
c dd 3456
d dq -14
segment .bss
res resq 1
segment .text
global _start
_start:
movsx rax, [a] ; here
movsx rbx, [b] ; here
movsxd rcx, [c] ; here
mov rdx, [d]
add rcx, rdx
add rbx, rcx
add rax, rbx
mov [res], rax
ret
推荐答案
对于大多数指令,寄存器操作数的宽度表示内存操作数的宽度,因为两个操作数的大小必须相同.例如mov rdx, [d]
表示mov rdx, qword [d]
,因为您使用了64位寄存器.
For most instructions, the width of the register operand implies the width of the memory operand, because both operands have to be the same size. e.g. mov rdx, [d]
implies mov rdx, qword [d]
because you used a 64-bit register.
但相同的 movsx
/ movsx
/movzx
始终需要显式指定的内存操作数的宽度.
movsx
/ movzx
with a memory source always need the width of the memory operand specified explicitly.
movsxd
助记符应隐含32位源大小. movsxd rcx, [c]
与NASM组装在一起,但显然与YASM组装在一起. YASM要求您编写dword
,即使它在那里不接受byte
,word
或qword
,并且也不接受movsx rcx, dword [c]
(即,它要求movsxd
助记符用于32位源操作数).
The movsxd
mnemonic is supposed to imply a 32-bit source size. movsxd rcx, [c]
assembles with NASM, but apparently not with YASM. YASM requires you to write dword
, even though it doesn't accept byte
, word
, or qword
there, and it doesn't accept movsx rcx, dword [c]
either (i.e. it requires the movsxd
mnemonic for 32-bit source operands).
在NASM中,movsx rcx, dword [c]
组装为movsxd
,但是movsxd rcx, word [c]
仍然被拒绝.即在NASM中,普通movsx
是完全灵活的,但movsxd
仍然是刚性的.为了人类的利益,我仍然建议使用dword
来使负载的宽度明确.
In NASM, movsx rcx, dword [c]
assembles to movsxd
, but movsxd rcx, word [c]
is still rejected. i.e. in NASM, plain movsx
is fully flexible, but movsxd
is still rigid. I'd still recommend using dword
to make the width of the load explicit, for the benefit of humans.
movsx rax, byte [a]
movsx rbx, word [b]
movsxd rcx, dword [c]
请注意,指令的操作数大小"(由操作数大小前缀确定为16位,或者由REX.W = 1使其确定为64位)是movsx
的目标宽度/movzx
.不同的源大小使用不同的操作码.
Note that the "operand size" of the instruction (as determined by the operand-size prefix to make it 16-bit, or REX.W=1 to make it 64-bit) is the destination width for movsx
/ movzx
. Different source sizes use different opcodes.
In case it's not obvious, there's no movzxd
because 32-bit mov
already zero-extends to 64-bit implicitly. movsxd eax, ecx
is encodeable, but not recommended (use mov
instead).
在AT& T语法中,不同的源宽度具有不同的助记符,例如movsb
或movsw
.目标大小是通常的后缀,因此您可以编写movsbq (%rsi), %rax
为显式或movsb (%rsi), %rax
以便汇编程序从%rax
推断目标大小.
In AT&T syntax, different source-widths have different mnemonics, like movsb
or movsw
. The destination size is a suffix as usual, so you can write movsbq (%rsi), %rax
to be explicit or movsb (%rsi), %rax
to let the assembler infer the destination size from %rax
.
有关您的源代码的其他内容:
Other stuff about your source code:
NASM/YASM允许您使用segment
关键字而不是section
,但实际上,您提供的是ELF节名称,而不是可执行段名称.另外,您可以将只读数据放入section .rodata
(作为文本段的一部分链接). ELF文件中的节和段有什么区别格式.
NASM/YASM allow you to use the segment
keyword instead of section
, but really you're giving ELF section names, not executable segment names. Also, you can put read-only data in section .rodata
(which is linked as part of the text segment). What's the difference of section and segment in ELF file format.
您不能从_start
中ret
.它不是函数,而是您的ELF入口点.堆栈上的第一件事是argc
,不是有效的返回地址.使用它可以干净地退出:
You can't ret
from _start
. It's not a function, it's your ELF entry point. The first thing on the stack is argc
, not a valid return address. Use this to exit cleanly:
xor edi,edi
mov eax, 231
syscall ; sys_exit_group(0)
请参见 x86 标签Wiki的问题,以获取指向以下链接的链接更有用的指南(以及底部的调试提示).
See the x86 tag wiki for links to more useful guides (and debugging tips at the bottom).
这篇关于yasm movsx,movsxd操作数2的无效大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!