NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: ironman on September 01, 2011, 09:17:22 PM
-
Hello,
I am trying to assemble a file that contains code which directly references the RIP register (note, I did not write this code, I am trying to use existing assembly). Here is an example (intel syntax):
addsd xmm0, [rip+0x484]
However, whenever I reference RIP, I get
error: symbol `rip' undefined
I checked and R_RIP isn't even defined in the regs.h file like R_RAX or R_RBP. I don't see why it shouldn't be though? How can I get NASM to handle code that directly references the RIP register? Thanks.
-
I have no experience with 64-bit code! As a WAG, try...
addsd xmm0, [rel $ +0x484]
If that doesn't do what the original code intends, get back to us.
Best,
Frank
-
Thanks Frank! That seems to work. Is there a reason NASM doesn't support this code syntax by default?
-
I don't know. We can't use IP or EIP either. For "consistency" maybe? What assembler is it that supports the syntax you showed?
Best,
Frank
-
GAS
.intel_syntax
addsd %xmm0, [%rip + 0x484]
works fine.
-Matt
-
This is x64 RIP-relative addressing. The RIP register is simply used as a base register to access offsets relative to it's position and used for Position Independent Code (PIC) (http://en.wikipedia.org/wiki/Position-independent_code).
-
Okay, thanks Matt! Nasm is not, strictly speaking "Intel syntax". Claims to be "similar to Intel's, but less complex". I'm not sure it's actually "less complex" in this particular case... and maybe not that "similar", either. For now, "that's the way it is".
We can do:
%idefine rip rel $
(the 'i' in "%idefine" makes it case-insensitive) That works in this case, but not if it were a label (which is probably more common?)
As an alternative to putting "rel" in the brackets, we can do:
default rel
... and it will apply throughout. However, we still need the '$' (unless it's a label), or Nasm burps up a warning... and emits different code. Since a label is probably more common, I hope this won't be too much of a problem.
Best,
Frank
-
However, whenever I reference RIP, I get
error: symbol `rip' undefined
I checked and R_RIP isn't even defined in the regs.h file like R_RAX or R_RBP. I don't see why it shouldn't be though? How can I get NASM to handle code that directly references the RIP register? Thanks.
There are no machine code instructions to let you access IP/EIP/RIP directly, so there is nothing missing in assembler. If you ever need to find out what address IP/EIP/RIP holds you have to call a routine designed to examine the ret address on the stack.
-
There are no machine code instructions to let you access IP/EIP/RIP directly, so there is nothing missing in assembler.
Exactly. Referencing the RIP register, while somewhat intuitive, was a hasty language design choice in other assemblers. The distinction is simply absolute, or relative.
-
bits 64
default rel
...
lea rax, [$]
...
Would this tell me current RIP without doing a call/pop?
(MUST upgrade my hardware!)
Best,
Frank
-
bits 64
default rel
...
lea rax, [$]
...
Would this tell me current RIP without doing a call/pop?
(MUST upgrade my hardware!)
Best,
Frank
lea eax, [$]
That works perfectly in 32-bit mode - thanks for the tip!
-
Heh! How about that? I never thought to try it in 32-bit code. I'm guessing that for Position Independent Code, it may not work. I'm guessing that if I tell ld "-shared", it's going to yell at me. In 32-bit code, '$' is a "relocatable value". In 64-bit code, with RIP-relative addressing, maybe not. 64-bit code is... different(!).
Best,
Frank
-
When in doubt, look at the generated opcodes...
;nasm -f bin -o test32.o test32.asm
[BITS 32]
lea eax,[$]
;ndisasm -b32 test32.o
00000000 8D0500000000 lea eax,[dword 0x0]
;nasm -f bin -o test64.o test64.asm
[BITS 64]
lea eax,[abs $]
lea eax,[rel $]
lea rax,[abs $]
lea rax,[rel $]
;ndisasm -b64 test64.o
00000000 8D042500000000 lea eax,[0x0]
00000007 8D05FAFFFFFF lea eax,[rel 0x7]
0000000D 488D04250D000000 lea rax,[0xd]
00000015 488D05F9FFFFFF lea rax,[rel 0x15]