gpt4 book ai didi

assembly - yasm movsx、movsxd 操作数 2 的大小无效

转载 作者:行者123 更新时间:2023-12-03 06:27:27 29 4
gpt4 key购买 nike

我正在尝试使用 yasm 汇编下面的代码。我在 yasm 报告错误“错误:操作数 2 的大小无效”的地方添加了“此处”注释。为什么会发生这个错误?

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 位寄存器。

但是一样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] (即,它需要 movsxd 助记符来表示 32 位源操作数)。

在 NASM 中,movsx rcx, dword [c] 汇编为 movsxd,但 movsxd rcx, word [c] 仍然被拒绝。即在 NASM 中,普通的 movsx 是完全灵活的,但 movsxd 仍然是刚性的。为了人类的利益,我仍然建议使用 dword 来明确负载的宽度。

movsx    rax,  byte [a]
movsx rbx, word [b]
movsxd rcx, dword [c]

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

<小时/>

如果不明显,没有 movzxd 因为 32-bit mov already zero-extends to 64-bit implicitlymovsxd eax, ecx 是可编码的,但不推荐(使用 mov 代替)。

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

有趣的事实:GAS 和 clang 确实允许将 movzb (%rsi)、%eax 作为 movzbl 之类的东西,但 GAS 仅具有额外的逻辑来允许消除歧义(必要时根据操作数(不仅仅是推断大小),例如 movsd (%rsi)、%xmm0 与 movsd。 (Clang12.0.1 实际上确实接受 movsb (%rcx), %eax 作为 movsbl,但 GAS 2.36.1 不接受,因此为了可移植性,最好明确使用符号扩展,对于零扩展来说也是一个不错的主意。)

<小时/>

有关源代码的其他内容:

NASM/YASM 允许您使用 segment 关键字而不是 section,但实际上您给出的是 ELF 节名称,而不是可执行段名称。此外,您还可以将只读数据放入 .rodata 部分(作为文本段的一部分链接)。 What's the difference of section and segment in ELF file format .

您无法从_startret。它不是一个函数,它是你的 ELF 入口点。堆栈上的第一件事是 argc,不是有效的返回地址。使用它可以干净地退出:

xor    edi,edi
mov eax, 231
syscall ; sys_exit_group(0)

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

关于assembly - yasm movsx、movsxd 操作数 2 的大小无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47350568/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com