首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >yasm movsx,movsxd操作数2的无效大小

yasm movsx,movsxd操作数2的无效大小
EN

Stack Overflow用户
提问于 2017-11-17 12:22:56
回答 1查看 1.7K关注 0票数 3

我正在尝试使用yasm来组装下面的代码。我在这里添加了‘这里’的注释,其中yasm报告了错误" error : 2“。为什么会发生这个错误?

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-18 03:19:19

对于大多数指令,寄存器操作数的宽度意味着内存操作数的宽度,因为两个操作数必须是相同的大小。mov rdx, [d]意味着mov rdx, qword [d],因为您使用了64位寄存器。

但同样的movsx / movzx助记符用于字节源和字源代码,因此除非源是寄存器(如movzx eax, cl),否则它是不明确的。另一个例子是crc32 r32, r/m8r/m16r/m32。(与movsx/zx不同,它的源大小可以和操作数大小一样宽。)

具有内存源的movsx / movzx 总是需要显式指定的内存操作数的宽度。

movsxd助记符应该意味着32位的源大小.movsxd rcx, [c]与NASM汇合,但显然与YASM不装配。YASM要求您编写dword,即使它在那里不接受bytewordqword,它也不接受movsx rcx, dword [c] (也就是说,它需要32位源操作数的movsxd助记符)。

在NASM中,movsx rcx, dword [c]组装为movsxd,但movsxd rcx, word [c]仍然被拒绝。也就是说,在NASM中,普通movsx是完全灵活的,但movsxd仍然是刚性的。为了人类的利益,我仍然建议使用dword来显式地显示负载的宽度。

代码语言:javascript
复制
movsx    rax,  byte [a]
movsx    rbx,  word [b]
movsxd   rcx, dword [c]

注意,指令的“操作数大小”(由操作数大小前缀确定,使其为16位,或REX.W=1为64位)是movsx / movzx的目标宽度。不同的源大小使用不同的操作码。

如果情况不太明显,就不会有movzxd,因为已经隐式地扩展到64位。movsxd eax, ecx是可编码的,但不推荐使用(使用mov代替)。

在AT&T语法中,您需要在助记符中显式指定源和目标宽度,比如movsbq (%rsi), %rax。GAS不允许您编写movsb (%rsi), %eax来推断目标宽度(操作数大小),因为movsb/movsw/etc是具有隐式(%rsi)、(%rdi)操作数的字符串-移动指令的助记符。

有趣的事实: GAS和clang确实允许使用movzb (%rsi), %eax作为movzbl,但是GAS只有额外的逻辑来允许在必要时根据操作数消除歧义(而不仅仅是推断大小),比如movsd (%rsi), %xmm0movsd。(Clang12.0.1实际上接受movsb (%rcx), %eax作为movsbl,但是GAS 2.36.1不接受,所以为了便于移植,最好用符号扩展来显式,对于零扩展也不是个坏主意。)

关于您的源代码的其他内容:

NASM/YASM允许您使用segment关键字而不是section,但实际上您是给ELF节名,而不是可执行段名。此外,您还可以将只读数据放入section .rodata (它作为文本段的一部分进行链接)。ELF文件格式的区段和段有什么不同?

你不能ret_start。这不是函数,是你的ELF入口点。堆栈上的第一件事是argc,而不是有效的返回地址。使用这个可以干净地退出:

代码语言:javascript
复制
xor    edi,edi
mov    eax, 231
syscall            ; sys_exit_group(0)

请参阅x86标记wiki,以获得指向更多有用指南的链接(以及底部的调试技巧)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47350568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档