flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > [fasmg] [rip+expr] with a non-absolute displacement

Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 4535
Location: vpcmpistri
bitRAKE 03 Jul 2026, 10:00
Subject: [rip+expr] with a non-absolute displacement — suggestion to reject at the instruction.

I ran into this producing MS COFF objects (COMDAT/`/OPT:REF` work). Writing this by mistake:
Code:
format MS64 COFF
section '.data' data readable writeable
v dq 0
section '.text' code readable executable
public f
f:      mov     rax,[rip+v]
        ret    

assembles silently to a RIP-relative encoding carrying an IMAGE_REL_AMD64_ADDR32 relocation on the displacement:
Code:
0: 48 8b 05 00 00 00 00    mov rax,[rip]
   3: IMAGE_REL_AMD64_ADDR32 .data    
Both link.exe and lld-link accept it without a peep, and at run time the EA is next_instruction + VA(v) — garbage. fasm 1.73.32 produces the identical object, so this is not a fasm2 regression; it follows directly from the documented semantics (mov [rip+3],sil ; manual RIP-relative addressing): the expression after rip+ is the displacement. The correct spellings are [v] (automatic) or {rip} / use rip to force the encoding — I'm not proposing any change to that.

The suggestion: a manual RIP displacement that is not an absolute quantity has no meaningful encoding in any output format, so reject it at the instruction instead of letting it become a bogus relocation (object formats) or a late cryptic error. In include/x86-2.inc:
Code:
--- a/include/x86-2.inc
+++ b/include/x86-2.inc
@@ -604,10 +604,15 @@
            rip_relative_address:
+               check   displacement relativeto 0
+               jno     invalid_rip_displacement
                compute mode, 0 scaleof (1 metadataof address_registers) shl 3
                compute mod, 0
                compute rm, 5
                compute displacement_size, 4
                exit
+           invalid_rip_displacement:
+               err     'displacement in manual RIP-relative addressing must be absolute'
+               exit    

What I verified changes and doesn't change (fasm2 g.l7xm, all cases tested):
  • Unchanged: [rip+3], [rip], [rip-7], [rip+b-a] (label differences), and [rip+label] under a numeric org (labels are plain numbers there — bit-for-bit fasm 1 compatible). The automatic [sym] path and use norip absolute addressing (legitimate ADDR32) go through direct_address, not this path, and are untouched.
  • New error: [rip+sym] in relocatable outputs (COFF/ELF), which today emits the silent bad relocation; and [rip+label] with an element-based org (PIC-style), which today fails anyway but with Error: variable term used where not expected. at the data-emission layer instead of at the instruction.
  • Not caught (deliberately): fixed-base PE, where labels reduce to plain numbers — same literal-VA displacement fasm 1 produces. The check only fires where the displacement cannot reduce to a number at all.

The caveat I can't rule out alone: this is a strictness increase over fasm 1, not parity — fasm 1 also emits the ADDR32-on-RIP combination for COFF. I can't construct a program where EA = next_instruction + relocated_VA is what anyone wants, but if there's a legitimate pattern relying on it (some loader-delta trick?), the check would break it. That's the question, really: is there any intended use of a relocatable term in a manual RIP displacement, or is it safe to call it an error?
Post 03 Jul 2026, 10:00
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8543
Location: Kraków, Poland
Tomasz Grysztar 03 Jul 2026, 12:04
bitRAKE wrote:
The caveat I can't rule out alone: this is a strictness increase over fasm 1, not parity — fasm 1 also emits the ADDR32-on-RIP combination for COFF. I can't construct a program where EA = next_instruction + relocated_VA is what anyone wants, but if there's a legitimate pattern relying on it (some loader-delta trick?), the check would break it. That's the question, really: is there any intended use of a relocatable term in a manual RIP displacement, or is it safe to call it an error?
This has been the theme of many discussions about fasm's design in the past, and the choice for fasm 1 usually was to permit unusual combinations when they are logically consistent, to allow emergent uses. It has been one of the cornerstones of what made fasm popular: allowing to combine things in unconventional, but predictable and logical manner, as we never know what uses may be found in the future. One day you might have a novel idea and find out that you can just do it, because the assembler does not try too hard to get in the way.

That said, I designed fasm2 the way it is (a package of headers for the fasmg engine) to allow such choices to be made individually when needed. We could have different sets of headers with different priorities.
Post 03 Jul 2026, 12:04
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.