With the following code, I attempt to "store" the lower two bytes of ebx in the two higher bytes, then use the lower order bx as a temporary variable for accessing an offset into "pool". Finally, I restore the original value (it only used the lower two bytes originally) by right shifting the data over.
rol ebx, 16
mov bl, dl
;(other operations involving bx)
mov [pool+bx], dword esi
shr ebx, 16
This assembles just fine with nasm, however I get the error
relocation truncated to fit: R_386_16 against `.data'
when linking. Any advice on how to bypass this error? Simply using another register isn't an option, as literally every register save esp and the segment registers are being used.
Edit: I assume someone will ask, so I'm using 32 Bit assembly
Because you used bx
in the effective address, the assembler thought you wanted a 16 bit address and hence generated 16 bit relocation that the linker was unhappy with. It probably wouldn't work in 32 bit mode anyway, since your variable is unlikely to be in the bottom 64k of the address space.
If you don't have any free registers maybe you can use the stack:
push ebx
mov bl, dl
;(other operations involving bx)
movzx ebx, bx
mov [pool+ebx], esi
pop ebx
You said only low 16 bits of ebx
were used. If that's the case for edx
as well, you can save dx
in the top 16 bits of ebx
, such as:
shl ebx, 16
mov bx, dx
;(other operations involving dx)
movzx edx, dx
mov [pool+edx], esi
mov dx, bx
shr ebx, 16
No, you can't save arbitrary values in segment registers.