flat assembler
Message board for the users of flat assembler.

Index > Main > sizeof(intruction) .. or something like it.

Author
Thread Post new topic Reply to topic
StarKnightD



Joined: 04 Jul 2007
Posts: 38
StarKnightD
does FASM have an ability to give the size of a particular instruction?

perhaps this is a better example of what I'm trying to do:

Code:
mov eax, address_of_next_instruction_beyond_jump
jCC procedure_address


ret
procedure_address:
; code for procedure goes here.
jmp eax    


This isn't very optimized code, from Intel's perspective (as far as the manuals are concerned), but it's very useful code nonetheless..

I suppose
Code:
push address_of_next_instruction_beyond_jump
jCC procedure_address


ret
procedure_address:
; code for procedure goes here.
ret    


would also be a useful form of this. personally, I'd like to avoid register usage, but I don't think that issue matters in this case.

either way, calculating the address would be far more prone to error.

if FASM doesn't have an ability to do this, any ideas on a macro?


EDIT: sorry to be editing a post long after it's been replied to, but I can't let the "register" reference stand... I meant that I'd like to avoid stack usage! I'm not sure what I was smokin' when I wrote that! Twisted Evil


Last edited by StarKnightD on 08 Sep 2008, 17:02; edited 1 time in total
Post 06 Sep 2008, 04:09
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17716
Location: In your JS exploiting you and your system
revolution
Use a label.
Code:
  push address_of_next_instruction_beyond_jump
  jCC procedure_address
address_of_next_instruction_beyond_jump:
  ;...
  ret
procedure_address:
  ; code for procedure goes here.
  ret    
Post 06 Sep 2008, 04:17
View user's profile Send private message Visit poster's website Reply with quote
StarKnightD



Joined: 04 Jul 2007
Posts: 38
StarKnightD
damn.. this is the situation I was trying to avoid.. I don't want to type a label everytime.. it's cumbersome and makes the code dirty. as far as the stack is concerned, it's usage has downsides. what if the function was never called: there is a memory leak in that second example I put up (the one you modified), since the stack will be modified, but never restored!

the register-style jumps have the advantage of their values being tossed when they're not used as well as when they are. personally, I think modifying the original jump condition so it jumps over a "call proc" on failure is far simpler than anything that employs the stack for this type of case. in the end, the stack example was an error on my part to even mention!

so were back to register usage, does anyone know of a way to avoid having to do this:

Code:
mov eax, $ + 3 ; there are issues about CS:IP's value at this point..
jCC proc

; do with eax whatever you please. either way it doesn't matter!

ret
proc:
; code goes here..
jmp eax    
Post 06 Sep 2008, 04:46
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
how about using CALL ?
Post 06 Sep 2008, 08:56
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
vid, didn't you notice jCC? Obviously, StarKnightD trying to conditionally call proc...

StarKnightD, isn't it what you're trying to do?
Code:
                jnCC     @f; note the inverse jump condition
                call     proc
@@:    
Then probably this is what you want:
Code:
;;; Iterate through possible condition codes and define macro with appropriate name

irps CC, a ae b be c e g ge l le o p pe po s z {
        macro call#CC proc \{
        local ..retaddr                 ; double-dot symbol name -- won't break local labels' attachment
                jn#CC    ..retaddr      ; note that we can't use @f/@@ pair as in above
                call     proc
        ..retaddr:                      ; or else we will obscurely redefine @@ on macro expansion
        \}
}

;;; Make sure that funny mnemonics (jnnge e.g.) get their valid equivalents

irps CC, a ae b be c e g ge l le o p s z {
        jnn#CC  equ      j#CC
}

;;; Parity isn't that ^^^ straightforward, handle special case

jnpe    equ     jpo
jnpo    equ     jpe    
This snippet was barely tested, caveat emptor. Wink
Post 06 Sep 2008, 14:00
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17716
Location: In your JS exploiting you and your system
revolution
StarKnightD wrote:
damn.. this is the situation I was trying to avoid.. I don't want to type a label everytime.. it's cumbersome and makes the code dirty.
I can't imagine how a sizeof.instruction would be any "cleaner"?
StarKnightD wrote:
as far as the stack is concerned, it's usage has downsides. what if the function was never called: there is a memory leak in that second example I put up (the one you modified), since the stack will be modified, but never restored!
Well sure there were many potential bugs, but I just used what you wrote and assumed you had some sort of stack-fix-up code in there that was not shown for brevity.
StarKnightD wrote:
the register-style jumps have the advantage of their values being tossed when they're not used as well as when they are. personally, I think modifying the original jump condition so it jumps over a "call proc" on failure is far simpler than anything that employs the stack for this type of case. in the end, the stack example was an error on my part to even mention!

so were back to register usage, does anyone know of a way to avoid having to do this:

Code:
mov eax, $ + 3 ; there are issues about CS:IP's value at this point..
jCC proc

; do with eax whatever you please. either way it doesn't matter!

ret
proc:
; code goes here..
jmp eax    
I still don't understand what you have against a label. That is the purpose of the label, to give you the address of the code position. If you try to use fixed offsets like $+x then you are likely to get yourself in trouble since instruction sizes are not fixed, especially JCCs which can be either the short or the long encoding.
Post 06 Sep 2008, 15:56
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
In case you still want "sizeof(instruction)" you can do it this way:
Code:
virtual at $
  instruction
size = $ - $$
end virtual    


Remember that with that you only got the size, the instruction won't form part of the executable until you write it again outside the virtual block (preferably right after it because some instructions could be smaller/larger if you place it in a different place)
Post 06 Sep 2008, 16:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17716
Location: In your JS exploiting you and your system
revolution
Here is a slightly simpler macro for callCC:
Code:
irp cc,c,z,e,s,a,b,g,l,ae,be,ge,le,o,p,pe,nc,nz,ne,ns,na,nb,ng,nl,nae,nbe,nge,nle,no,np,po {
 macro call#cc dest \{
         \local .i,.j,i
         .i=$
            j#cc .j
             call dest
       .j=$
            load i from .i
              store (i xor 1) at .i
       \}
}    
Post 06 Sep 2008, 16:30
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
revolution, you're great as usual. Not only your example extends and corrects mine, it cause curious mind to find the explanation why (i xor 1) inverts CC.
Post 06 Sep 2008, 23:13
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
That's how instructions are encoded. Lowest bit of JCC opcode inverts the condition.
Post 07 Sep 2008, 09:04
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
vid, thanks for outright spoiler... Wink I've already knew that about lsb of jCC opcode, and hope that somebody who doesn't know will ask himself "why" and dig some references to find out...
Post 07 Sep 2008, 14:07
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
revolution and vid,

It just strucks my mind: what if somebody develops call macro that will inline proc/endproc block (if it is called only once) ? Overkill for now, but nevertheless it's easy to modify call#cc for the case of long j#cc encoding...

P.S. This post is a result of my own medicine: "dig some references" Wink
Post 07 Sep 2008, 14:27
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
baldr, I thought about it once but I haven't been able to fix the lack of forward reference feature that the current implementation enjoys.
Post 07 Sep 2008, 15:05
View user's profile Send private message Reply with quote
StarKnightD



Joined: 04 Jul 2007
Posts: 38
StarKnightD
revolution: it's "cleaner" in an arbitrary sense.. I think it looks like a hotfix/patch to use a label. There are people who still use
Code:
mov al, const1
mov ah, const2
; instead of
mov ax, (const2 shl 8) + const1    

personally, the cost of the latter is well worth the benefit.

as for the examples, they look great! I definitely need to get into the macro programming language built into FASM..

thanks for the help everyone, I didn't expect it to get so many responses Very Happy
Post 07 Sep 2008, 16:56
View user's profile Send private message Reply with quote
StarKnightD



Joined: 04 Jul 2007
Posts: 38
StarKnightD
I've been looking over the examples, and trying my own.. this is a fairly simply macro, but it looks like it works.
Code:
macro jCC Which_Register_To_Use, Condition_Code, Function_Address
{
   local return_address
   mov Which_Register_To_Use, return_address
   Condition_Code Function_Address
   return_address:
}

;.
;.
;.

   cmp eax, ebx
   jCC rax, jz, Function    
Post 08 Sep 2008, 16:56
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
But, the function must use jmp rax instead of ret, right? Sorry for re-asking but what is the problem with call instruction (particularly with revolution's callCC)?

Well of course the function could have a "push rax" as its first instruction so you can use ret but ret should be paired with a call, otherwise it is very likely that the processor will mispredict the return address (or the return address buffer is an obsolete thing now?).

[edit]No, the return stack buffer is not obsolete at all...

Optimizing Assembly [Agner Fog 2008] wrote:
Returns are predicted by means of a so-called return stack buffer which is a first-in-last-out
buffer that mirrors the return addresses pushed on the stack. A return stack buffer with 16
entries can correctly predict all returns for subroutines at a nesting level up to 16. If the
subroutine nesting level is deeper than the size of the return stack buffer then the failure will
be seen at the outer nesting levels, not the presumably more critical inner nesting levels. A
return stack buffer size of 8 or 16 is therefore sufficient in most cases, except for deeply
nested recursive functions.
The return stack buffer will fail if there is a call without a matching return or a return without
a preceding call. It is therefore important to always match calls and returns. Do not jump out
of a subroutine by any other means than by a RET instruction. And do not use the RET
instruction as an indirect jump. Far calls should be matched with far returns.
Post 08 Sep 2008, 17:09
View user's profile Send private message Reply with quote
StarKnightD



Joined: 04 Jul 2007
Posts: 38
StarKnightD
Quote:

But, the function must use jmp rax instead of ret, right? Sorry for re-asking but what is the problem with call instruction (particularly with revolution's callCC)?


the idea is to avoid the stack entirely..

Code:
macro jCC Which_Register_To_Use, Condition_Code, Function_Address
{
   local return_address
   mov Which_Register_To_Use, return_address
   Condition_Code Function_Address
   return_address:
}

;.
;.
;.

   cmp eax, ebx
   jCC rax, jz, Function
   ; modify rax/eax however you please here, since rax has
   ; already been thrown out/used as a possible return address.
   ret
Function:
;... code
jmp rax    
I read the snippet, and it appears that a call must be paired with a ret. so that doesn't apply in this case.. I'm not actually trying to implement a call, I simply want a "cheap" single-level function, as in zero-recursion-possible.

but yeah, it's "bad" performance wise to use jumps with registers.. jumps with registers aren't predicted at all according to one of the intel manuals that I read a while ago. The quote you put up is new to me, however.
Post 09 Sep 2008, 15:28
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
StarKnightD, your idea about calling function w/o using stack looks good. Use stack when it's necessary, for recursion or RPN calculator Wink. Compilers now usually use esp-related addressing for stack manipulations, omitting stack frame altogether and freeing ebp (12.5% of GPR pool, not bad Wink for flat model (ss==ds), so why do we have to use stack just to call leaf function (i.e. function that does not call other functions)? And you can always save link register (register, holding return address) before nested call, just push it. I can't remember but have a strong feeling that there was an architecture using similar approach...

LocoDelAssembly, how much clocks your highly-optimized always-correctly-predicted-branch code will take before next OS call or context switch? Wink

Cooperative multitasking has it's merits, you can yield execution in appropriate places...
Post 10 Sep 2008, 22:51
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

LocoDelAssembly, how much clocks your highly-optimized always-correctly-predicted-branch code will take before next OS call or context switch? Wink


How often do you expect this to happen? Of course if the leaf function performs some heavy work this will happen a lot but why sacrifice this feature on leaf functions that are very unlikely to suffer of OS interruption?

Quote:
And you can always save link register (register, holding return address) before nested call, just push it. I can't remember but have a strong feeling that there was an architecture using similar approach...


I think it is MIPS architecture.
Post 10 Sep 2008, 23:44
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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.