Assembly 16位寄存器作为偏移量的有效地址计算

Assembly 16位寄存器作为偏移量的有效地址计算,assembly,nasm,intel-syntax,Assembly,Nasm,Intel Syntax,在下面的代码中,我尝试将ebx较低的两个字节“存储”在较高的两个字节中,然后将较低的顺序bx用作临时变量,用于访问“池”中的偏移量。最后,我通过右移数据恢复原始值(它最初只使用较低的两个字节) rol ebx, 16 mov bl, dl ;(other operations involving bx) mov [pool+bx], dword esi shr ebx, 16 nasm可以很好地进行组装,但是我得到了错误 根据“.data”截断重新定位以适应:R_386_16 链接

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

rol ebx, 16

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

shr ebx, 16
nasm可以很好地进行组装,但是我得到了错误

根据“.data”截断重新定位以适应:R_386_16

链接时。有没有关于如何绕过此错误的建议?简单地使用另一个寄存器不是一个选项,因为实际上每个寄存器都在使用


编辑:我假设有人会问,所以我使用32位汇编来截断bx和movzx ebx,bx然后将其用作表mov[pool+ebx]的索引,esi:)

,因为您在有效地址中使用了
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

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

遗憾的是,我需要保留移动到ebx上两个字节的数据,因此截断实际上不起作用。知道我是否可以将偏移量卸载到池中的未使用段寄存器中吗?