flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
revolution 06 Sep 2008, 04:17
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 |
|||
![]() |
|
StarKnightD 06 Sep 2008, 04:46
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 |
|||
![]() |
|
vid 06 Sep 2008, 08:56
how about using CALL ?
|
|||
![]() |
|
baldr 06 Sep 2008, 14:00
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 @@: 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 ![]() |
|||
![]() |
|
revolution 06 Sep 2008, 15:56
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. 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! 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! |
|||
![]() |
|
LocoDelAssembly 06 Sep 2008, 16:12
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) |
|||
![]() |
|
revolution 06 Sep 2008, 16:30
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 \} } |
|||
![]() |
|
baldr 06 Sep 2008, 23:13
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.
|
|||
![]() |
|
vid 07 Sep 2008, 09:04
That's how instructions are encoded. Lowest bit of JCC opcode inverts the condition.
|
|||
![]() |
|
baldr 07 Sep 2008, 14:07
vid, thanks for outright spoiler...
![]() |
|||
![]() |
|
baldr 07 Sep 2008, 14:27
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" ![]() |
|||
![]() |
|
LocoDelAssembly 07 Sep 2008, 15:05
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.
|
|||
![]() |
|
StarKnightD 07 Sep 2008, 16:56
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 ![]() |
|||
![]() |
|
StarKnightD 08 Sep 2008, 16:56
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 |
|||
![]() |
|
LocoDelAssembly 08 Sep 2008, 17:09
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 |
|||
![]() |
|
StarKnightD 09 Sep 2008, 15:28
Quote:
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 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. |
|||
![]() |
|
baldr 10 Sep 2008, 22:51
StarKnightD, your idea about calling function w/o using stack looks good. Use stack when it's necessary, for recursion or RPN calculator
![]() ![]() LocoDelAssembly, how much clocks your highly-optimized always-correctly-predicted-branch code will take before next OS call or context switch? ![]() Cooperative multitasking has it's merits, you can yield execution in appropriate places... |
|||
![]() |
|
LocoDelAssembly 10 Sep 2008, 23:44
Quote:
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. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.