【问题标题】:Operand size conflict in x86 Assembly?x86 程序集中的操作数大小冲突?
【发布时间】:2023-03-14 08:18:01
【问题描述】:

我是第一次尝试组装的新手程序员。如果这是一个非常蹩脚的问题,请提前道歉。

我在 EAX 寄存器中存储了一个字符,但我需要将它移动到我的 DL 寄存器中。当我尝试: mov dl, eax 我收到错误 C2443:操作数大小冲突。我知道 eax 寄存器是 32 位的,而 dl 是 8 位的……我在做什么吗?我该如何解决这个问题。

【问题讨论】:

    标签: assembly x86


    【解决方案1】:

    你想要的大概是:

    movzx edx, al
    

    这会将 al 复制到 dl 并将 edx 的其余部分填充为零。这条指令相当于这两条指令:

    xor edx, edx 
    mov dl, al
    

    【讨论】:

    • 我更喜欢这个。 movzx 负责处理所有尾随位。是的一些抽象! (我的热情应该暴露我缺乏组装经验)。
    • 另请注意,movzx / movsx 可以使用内存源操作数,用于字节或字在内存中的其他用例。
    【解决方案2】:

    试试

    xor edx,edx
    mov dl, al
    

    也许?将 edx 的“不必要的”高位清零的第一条指令(可选),然后将低 8 从 eax 移动到 edx。

    正如其他人所指出的,movzx 是一步完成的。值得一提的是,如果你在 al 中有一个 signed 值,你可以使用 "movsx edx, al" 用 al 的 msb 的副本填充 edx 的高位,从而将 al 的有符号 32 位表示形式放入 edx。

    【讨论】:

    • 没错。 EAX 寄存器为 32 位宽,而 DL 仅为 8 位。您需要将 AL 移动到 DL,AL 是 EAX 的子集。
    • 我不明白第一条指令。 xor edx,edx 不会将 %edx 中的所有位清零吗?
    • @JS Bangs:是的,这通常是你想要的。最初的问题没有说明保存 EDX 的其余部分,因此为了安全起见,最好将其归零。不然里面会有乱七八糟的东西,当你去往栈上push什么的时候,会得到意想不到的结果。
    【解决方案3】:

    如果你只想访问 eax 的低 8 位,那么使用 al:

    mov dl, al
    

    您可以通过更改开头或结尾的字母来访问每个通用寄存器的低 8 位、16 位或 32 位。对于寄存器 eax,使用 eax 表示使用所有 32 位,ax 是低 16 位,al 是低 8 位。 ebx 的等价物分别是 ebx、bx 和 bl,依此类推。

    请注意,如果您修改寄存器的低 16 位或 8 位,则高位不会改变。例如,如果你在 eax 中加载所有 1,然后将 0 加载到 al 中,那么 eax 的低 8 位将是 0,而高 24 位将是 1。

    mov eax, -1 ; eax is all ones
    mov al, 0 ; higher 24 bits are ones, lower 8 bits are zeros
    

    【讨论】:

    • 将 al 移入 dl 是基本情况。零填充或符号扩展可能是必要的,也可能不是必要的,因为在选择手动编码组件时,您是 - 或者应该是 - 在最低限度的基础解决方案之后:“很高兴拥有”是一种昂贵的奢侈品,自然会被排除在外。
    • 在现代 x86(尤其是 Intel)上,movzx edx, al 比使用 mov dl, al 合并到 EDX 的旧值中有效。在 IvyBridge 之后的 Intel CPU 上,它可以从 mov-elimination 中受益并以零延迟运行。请参阅 Can x86's MOV really be "free"? Why can't I reproduce this at all?Why doesn't GCC use partial registers?。在 AMD CPU 上,它只是避免了错误的依赖,即使您只计划在 DL 上使用 8 位操作数大小,这仍然很好。
    猜你喜欢
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    相关资源
    最近更新 更多