On the other hand, VALUE(%rip) is interpret as VALUE+%rip without that magic.
But when I do (expression with labels)(%rip), it does the former magic screwing up my calculations and there is no way to convince not to do it..
The only way I could get RIP relative addressing to absolute address, is to define the value in another .S, so that GAS does it magic, like this:
Code: Select all
.global _vga_base
_vga_base=0xb8000
Code: Select all
.extern _vga_base
mov $0x0f65, %ax
mov %ax, (_vga_base+0x10)(%rip)
Code: Select all
0x80002000c0 <_start> mov $0xf65,%ax
0x80002000c4 <_start+4> mov %ax,-0x1480bb(%rip) # 0x80000b8010
====
Edit3: This is just not fair. GAS does something nasty, as the following works:
Code: Select all
mov %ax, (0xB8010-_start)(%rip)
mov %ax, (0xB8010-_start)(%rip)
mov %ax, (0xB8010-_start)(%rip)
Code: Select all
0x80002000c4 <_start+4> mov %ax,-0x1480bb(%rip) # 0x80000b8010
0x80002000cb <_start+11> mov %ax,-0x1480c2(%rip) # 0x80000b8010
0x80002000d2 <_start+18> mov %ax,-0x1480c9(%rip) # 0x80000b8010
My %rip relative addressing is off by 4, and I cannot figure out why.
Assume the following code will be linked at 2M but loaded to virtual address X+2M, and VGA memory will be mapped at X+0xB8000.
I want to write a character at a fixed location using the following:
Code: Select all
mov $0x0f65, %ax
mov %ax, (0xB8010-.)(%rip)
However, the memory address is off by 4, so I have to use the following to get correct result:
Code: Select all
mov $0x0f65, %ax
mov %ax, (0xB8010+4-.)(%rip)
Edit2: There is something fundamentally wrong with this, but I cant figure it out. If I replicate the statement few times, each one gets a different address
(as if the dot refers to _start symbol, not current location):
Code: Select all
0x80002000c4 <_start+4> mov %ax,-0x1480bb(%rip) # 0x80000b8010
0x80002000cb <_start+11> mov %ax,-0x1480c9(%rip) # 0x80000b8009
0x80002000d2 <_start+18> mov %ax,-0x1480d7(%rip) # 0x80000b8002