yasm movsx,movsxd操作数2的无效大小 [英] yasm movsx, movsxd invalid size for operand 2

查看:265
本文介绍了yasm movsx,movsxd操作数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,即使它在那里不接受bytewordqword,并且也不接受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.

如果不明显,则没有movzxd,因为

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语法中,不同的源宽度具有不同的助记符,例如movsbmovsw.目标大小是通常的后缀,因此您可以编写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.

您不能从_startret.它不是函数,而是您的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)

请参见标签Wiki的问题,以获取指向以下链接的链接更有用的指南(以及底部的调试提示).

See the x86 tag wiki for links to more useful guides (and debugging tips at the bottom).

这篇关于yasm movsx,movsxd操作数2的无效大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆