【问题标题】:Effective Address Calculation with 16 bit register as offset以 16 位寄存器为偏移量的有效地址计算
【发布时间】:2012-12-31 00:43:03
【问题描述】:

使用下面的代码,我尝试将 ebx 的低两个字节“存储”在两个高字节中,然后使用低阶 bx 作为临时变量来访问“池”中的偏移量。最后,我通过右移数据恢复了原始值(它最初只使用了低两个字节)。

rol ebx, 16

mov bl, dl
;(other operations involving bx)    
mov [pool+bx], dword esi

shr ebx, 16

这与 nasm 组装得很好,但是我得到了错误

重定位被截断以适应:R_386_16 针对 `.data'

链接时。有关如何绕过此错误的任何建议?简单地使用另一个寄存器不是一种选择,因为实际上每个寄存器都保存 esp 并且正在使用段寄存器。

编辑:我假设有人会问,所以我使用的是 32 位程序集

【问题讨论】:

    标签: assembly nasm intel-syntax


    【解决方案1】:

    因为您在有效地址中使用了bx,所以汇编器认为您想要一个 16 位地址,因此生成了链接器不满意的 16 位重定位。无论如何,它可能无法在 32 位模式下工作,因为您的变量不太可能位于地址空间的底部 64k 中。

    如果您没有任何空闲寄存器,也许您可​​以使用堆栈:

    push ebx
    mov bl, dl
    ;(other operations involving bx)
    movzx ebx, bx
    mov [pool+ebx], esi
    pop ebx
    

    您说只使用了ebx 的低 16 位。如果edx也是这样,可以将dx保存在ebx的前16位,如:

    shl ebx, 16
    mov bx, dx
    ;(other operations involving dx)
    movzx edx, dx
    mov [pool+edx], esi
    mov dx, bx
    shr ebx, 16
    

    不,您不能在段寄存器中保存任意值。

    【讨论】:

      【解决方案2】:

      用 movzx ebx,bx 截断 bx 然后将其用作表 mov [pool+ebx],esi 的索引 :)

      【讨论】:

      • 遗憾的是,我需要保留移动到 ebx 高两个字节的数据,因此截断实际上不起作用。知道是否可以将偏移量卸载到未使用的段寄存器中吗?
      猜你喜欢
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 2018-04-03
      • 2011-01-29
      相关资源
      最近更新 更多