Find the answer to your Linux question:
Results 1 to 4 of 4
Hi...I'm teaching myself some AMD 64 bit assembler programing and I'm curious about RIP relative addressing. The docs that I've read state "You are recommended to use RIP relative addressing ...
  1. #1
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714

    AMD 64 bit RIP-relative addressing

    Hi...I'm teaching myself some AMD 64 bit assembler programing and I'm curious about RIP relative addressing. The docs that I've read state "You are recommended to use RIP relative addressing whenever possible to reduce code size" now my question is, is this the code size reduction they are talking about

    Code:
    example code 1 RIP-relative addressing
    
    .section .data
    	mydata: .long 0
    
    .section .bss
    
    .section .text
    	.global _start
    _start:
    			movq	$64, mydata(%rdi)
    Code:
    example code 2
    .section .data
    	mydata: .long 0
    
    .section .bss
    
    .section .text
    	.global _start
    _start:
    			movq	$64, mydata
    and the results

    Code:
    example 1 RIP-relative addressing
    code1:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    00000000004000b0 <_start>:
      4000b0:	48 c7 87 bc 00 60 00 	movq   $0x40,0x6000bc(%rdi)
      4000b7:	40 00 00 00
    Code:
    example 2
    code2:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    00000000004000b0 <_start>:
      4000b0:	48 c7 04 25 bc 00 60 	movq   $0x40,0x6000bc
      4000b7:	00 40 00 00 00
    are we talking about a one byte reduction in code size every time I use RIP relative addressing?

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    First of all, I don't have any experience with 64-bit programming.

    But I'm assuming you're referring to this page.

    I've skimmed through that page, and also through this page. It shows that there are several advantages to using RIP relative addressing, and I am familiar with the concepts, because I've written a linking loader or two in my day.
    1. As you mention, you save some space in the instruction itself.
    2. This translates somewhat into speed, since over the long haul fewer bytes of memory need be retrieved to fetch instructions.
    3. Beyond that, the assembled code is simpler. You have more position independent instructions, ones for which the assembler doesn't need to advise the linker of how to fix up the instruction in question. This is a minor detail, but if you're generating megabytes of code (which you might if you're using a compiler to generate the assembly language code), then you'll end up with a tighter, simpler, cleaner compilation / assembly / linking process.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  3. #3
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Thanks for the reply Bill, I did read the two links that you included and found them very informative but I still have difficulties understanding why this is so significant. Maybe if I understood shared objects better I would see the purpose...Thanks Gerard

    I found this link for 32 bit machines
    Dynamic Linking in Linux and Windows, part one

    maybe understanding shared objects in a 32 bit environment will help me to see the the significance of 64 bit RIP relative addressing...Thanks again

  4. #4
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    One of the problems that I had with RIP relative addressing was how did the code know how far mydata data was from the next rip

    i.e. movq $8, mydata(&#37;rip)

    well according to this snippet below the linker calculates the displacement between mydata and the next rip

    6000c8 = address for mydata
    4000bb = address for next instruction %rip

    and the difference is 20000d = 6000c8 - 4000bb

    4000b0: 48 c7 05 0d 00 20 00 movq $0x8,0x20000d(%rip) as seen below

    and the second instruction is 200002 = 6000c8 - 4000c6

    4000bb: 48 c7 05 02 00 20 00 movq $0x8,0x200002(%rip) as seen below

    Code:
    section .data
    	mydata: .long 0
    
    .section .bss
    
    .section .text
    	.global _start
    _start:
    			movq	$8, mydata(%rip)
    			movq	$8, mydata(%rip)	
    			nop
    			nop
    
    
    codefile:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    00000000004000b0 <_start>:
      4000b0:	48 c7 05 0d 00 20 00 	movq   $0x8,0x20000d(%rip)        # 6000c8 <mydata>
      4000b7:	08 00 00 00 
      4000bb:	48 c7 05 02 00 20 00 	movq   $0x8,0x200002(%rip)        # 6000c8 <mydata>
      4000c2:	08 00 00 00 
      4000c6:	90                   	nop    
      4000c7:	90                   	nop
    This clears up a fundamental problem I was having with RIP relative addressing...now if I could understand GOT/PLT and shared objects, that would be something

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...