1

使用以下代码,我尝试将 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 位程序集

4

2 回答 2

2

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

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

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

你说只使用了低 16 位ebx。如果也是这种情况edx,您可以保存dx在 的前 16 位中ebx,例如:

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

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

于 2012-12-31T01:40:46.127 回答
0

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

于 2012-12-31T01:18:58.937 回答