flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > [fasmg] Cannot generate code for jz macro

Author
Thread Post new topic Reply to topic
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 01 Mar 2017, 16:34
Code:
macro jz? dest*
  local addr
  addr = dest - $ - 2
  if addr >= -128 & addr < 128
    db 01110100b
    db addr
  else
    err asmerr_jmp__outof_range
  end if
end macro

NNN = 127

lbl_a:
    db 6
    jz lbl_a
    jz lbl_b
    db NNN dup 0
lbl_b:
    


This piece fails with error "Cannot generate code within the allowed number of passes" for NNN = 128 and 129. First I thought it's because it cannot compute lbl_b position, but it works for NNN 127 and below, as well as for NNN = 130 and above.

If not a bug, what is the exact reason so that I could forsee such behavior in the future? Thanks in advance
Post 01 Mar 2017, 16:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 01 Mar 2017, 16:42
That appears to be the same problem as this:
https://board.flatassembler.net/topic.php?p=178826#178826

There is no solution unless you force the longer encoding with a small sized offset. You will have to change the macro to detect it. Maybe create a new variable that keeps track of previous passes attempts. Or perhaps change the "else" block to create two bytes of dummy data to match the other block.
Post 01 Mar 2017, 16:42
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 01 Mar 2017, 17:00
Actually in this specific case there is a simple solution. Compare how is it done in examples/x86/include/8086.inc:
Code:
macro x86.short_jump opcode,dest
        x86.parse_jump_operand @dest,dest
        if @dest.type = 'imm' & ( @dest.jump_type = 'short' | ~ @dest.jump_type )
                if @dest.imm relativeto 0 & (@dest.imm < 0 | @dest.imm >= 10000h)
                        err 'value out of range'
                end if
                db opcode
                if @dest.imm-($+1)<80h & @dest.imm-($+1)>=-80h
                        db @dest.imm-($+1)
                else
                        err 'relative jump out of range'
                        db ?
                end if
        else
                err 'invalid operand'
        end if
end macro    
All that you need is to ensure that the offsets remain stable no matter if condition is fulfilled, so even in case of error generate the fields of appropriate length:
Code:
macro jz? dest*
  local addr 
  addr = dest - $ - 2
  db 01110100b
  if addr >= -128 & addr < 128
    db addr 
  else 
    err asmerr_jmp__outof_range
    db ?
  end if 
end macro 

NNN = 128

lbl_a: 
    db 6 
    jz lbl_a 
    jz lbl_b 
    db NNN dup 0 
lbl_b:    
Your problem was caused originally by the fact that when the relative offset was out of range, no bytes for instruction opcode were generated and therefore the relative offset shortened, leading to contradiction. You could read that statement as "if this block of code is longer than X, this instruction is not generated". When not generating an instruction causes the block to be shorter than X, that statement becomes contradictory.
Post 01 Mar 2017, 17:00
View user's profile Send private message Visit poster's website Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 01 Mar 2017, 17:13
Yeah, adding a tracking variable did the trick, thanks!
Post 01 Mar 2017, 17:13
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 01 Mar 2017, 17:19
Thank you for the explanation, Tomasz. Without it that db ? part in your macros would remain unclear
Post 01 Mar 2017, 17:19
View user's profile Send private message 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.