News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Signed Flags

Started by habran, October 12, 2014, 06:27:37 AM

Previous topic - Next topic

habran

Hi there,

I have added these signed flags to JWasm:
  SCARRY?           JGE    Sign flag = overflow flag               
  !SCARRY?            JL     Sign flag != overflow flag             
  SZERO?             JLE    Zero flag is set or sign != overflow   
  !SZERO?            JG     Zero flag is clear and sign = overflow 


I have encountered this C source:

  //Align to 16 pixel
  ptScale.x+=ptScale.x % 16;


it is compiled to this:

mov edx, DWORD PTR ptScale
mov ecx, edx
and ecx, -2147483633 ; ffffffff8000000fH
jge SHORT $LN10
dec ecx
or ecx, -16
inc ecx
$LN10:
add edx, ecx
  mov DWORD PTR ptScale, edx


we can write it like this:

  mov eax,ptScale.x                                   
and eax,8000000Fh
jge @F
dec eax               
or eax, -16                                 
inc eax
@@:
add ptScale.x, eax


assembled to:

  mov eax,ptScale.x                                   
000000013F8411C7 8B 84 24 90 00 00 00 mov         eax,dword ptr [ptScale] 
and eax,8000000Fh
000000013F8411CE 25 0F 00 00 80       and         eax,8000000Fh 
jge @F
000000013F8411D3 7D 07                jge         main+1Dh (013F8411DCh) 
dec eax               
000000013F8411D5 FF C8                dec         eax 
or eax, -16                                 
000000013F8411D7 83 C8 F0             or          eax,0FFFFFFF0h 
inc eax
000000013F8411DA FF C0                inc         eax 
@@:
add ptScale.x, eax
000000013F8411DC 01 84 24 90 00 00 00 add         dword ptr [ptScale],eax 

it would look better if we write it like this:

    mov eax,ptScale.x
    and eax, 8000000fH
    .if (SCARRY?)
      dec eax
      or eax, -16
      inc eax
    .endif
    add ptScale.x, eax

assembled to:

    mov eax,ptScale.x
000000013FCB11E3 8B 84 24 90 00 00 00 mov         eax,dword ptr [ptScale] 
    and eax, 8000000fH
000000013FCB11EA 25 0F 00 00 80       and         eax,8000000Fh 
    .if (SCARRY?)
000000013FCB11EF 7D 07                jge         main+39h (013FCB11F8h) 
      dec eax
000000013FCB11F1 FF C8                dec         eax 
      or eax, -16
000000013FCB11F3 83 C8 F0             or          eax,0FFFFFFF0h 
      inc eax
000000013FCB11F6 FF C0                inc         eax 
    .endif
    add ptScale.x, eax
000000013FCB11F8 01 84 24 90 00 00 00 add         dword ptr [ptScale],eax

your comments would be appreciated :biggrin:

if you agree about it I will post both 32bit and 64bit JWasm.exe here
Cod-Father

dedndave

these are the flag operators supported by MASM:
ZERO?
OVERFLOW?
SIGN?
CARRY?
PARITY?


these are the x86 conditional branch instructions (not including LOOPxx instructions):
------------------------------------------------------------------------
Group     Instruction  Description               Condition       Aliases
------------------------------------------------------------------------
Equality  JZ           Jump if equal             ZF=1            JE
          JNZ          Jump if not equal         ZF=0            JNE

Unsigned  JA           Jump if above             CF=0 and ZF=0   JNBE
          JAE          Jump if above or equal    CF=0            JNC JNB
          JB           Jump if below             CF=1            JC JNAE
          JBE          Jump if below or equal    CF=1 or ZF=1    JNA

Signed    JG           Jump if greater           SF=OF or ZF=0   JNLE
          JGE          Jump if greater or equal  SF=OF           JNL
          JL           Jump if less              SF<>OF          JNGE
          JLE          Jump if less or equal     SF<>OF or ZF=1  JNG
          JO           Jump if overflow          OF=1
          JNO          Jump if no overflow       OF=0
          JS           Jump if sign              SF=1
          JNS          Jump if no sign           SF=0

Parity    JP           Jump if parity            PF=1            JPE
          JNP          Jump if no parity         PF=0            JPO


it would be nice if the assembler "examined" combinations to see if code reduction is possible
for example, the source:
    .repeat
        add     eax,dwTestVar
    .until !CARRY? && !ZERO?

would generate the code:
@@:     add     eax,dwTestVar
        jbe     @B


a couple of advantages:
1) The programmer doesn't have to consciously check flag conditions against branch instructions.
   If the statement allows the use of the shorter form, substitution takes place automatically.
2) No change in current list of reserved keywords.
   No need for SCARRY? or SZERO? operators.

habran

#2
Hi Dave,
Thanks for replaying

check this code:

    mov eax,ptScale.x
000000013FCF11F1 8B 84 24 90 00 00 00 mov         eax,dword ptr [ptScale] 
    and eax, 8000000fH
000000013FCF11F8 25 0F 00 00 80       and         eax,8000000Fh 
    .if (CARRY? && SIGN?)
000000013FCF11FD 73 09                jae         main+49h (013FCF1208h) 
000000013FCF11FF 79 07                jns         main+49h (013FCF1208h) 
      dec eax
000000013FCF1201 FF C8                dec         eax 
      or eax, -16
000000013FCF1203 83 C8 F0             or          eax,0FFFFFFF0h 
      inc eax
000000013FCF1206 FF C0                inc         eax 
    .endif
    add ptScale.x, eax
000000013FCF1208 01 84 24 90 00 00 00 add         dword ptr [ptScale],eax

now compare it with the above one with SCARRY?
Cod-Father

dedndave

yah - there is no Jcc for (carry=0 AND sign=0)  :P

typically, carry is used for unsigned operations and sign is used for signed operations

habran

So you now do agree with me that SCARRY? is actually not so SCARY  ;)
Cod-Father

TouEnMasm

More sign are a good idea
Quote
ZERO?
OVERFLOW?
SIGN?
CARRY?
PARITY?
;-----------------------------------
SCARRY?           JGE    Sign flag = overflow flag               
  !SCARRY?            JL     Sign flag != overflow flag             
  SZERO?             JLE    Zero flag is set or sign != overflow   
  !SZERO?            JG     Zero flag is clear and sign = overflow 

Fa is a musical note to play with CL

habran

ToutEnMasm MERCIE BEAUCOUP :t
Cod-Father

dedndave

;*****************************
; SIGNED OPERATIONS
;*****************************

;JG           Jump if greater           SF=OF or ZF=0
;JGE          Jump if greater or equal  SF=OF
;JL           Jump if less              SF<>OF
;JLE          Jump if less or equal     SF<>OF or ZF=1
;
;if this code were supported, then signed operations would be feasible:

;   .if SIGN?==OVERFLOW?        ;MASM generates error
;       nop
;   .endif

;the assembler would also need to code:
;"(SIGN?==OVERFLOW?) || (!ZERO?)" as a JG instruction
;and
;"(SIGN?!=OVERFLOW?) || (ZERO?)" as a JLE instruction

;other combinations form the inverted logic of the same instructions
;for instance, ".if xxx" performs code if xxx is true
;the inverse logic is used in ".until xxx", where the branch occurs if xxx is not true


;*****************************
; UNSIGNED OPERATIONS
;*****************************

;JA           Jump if above             CF=0 and ZF=0

    .if !CARRY? && !ZERO?
        nop
    .endif

;MASM assembles that code as:

        jb      label0
        jz      label0
        nop
label0:

;it would be nice if it was coded as:

        ja      label0
        nop
label0:

;-----------------------------

;JBE          Jump if below or equal    CF=1 or ZF=1

    .if CARRY? || ZERO?
        nop
    .endif

;MASM assembles that code as:

        jb      label1
        jnz     label2
label1: nop
label2:

;it would be nice if it was coded as:

        jbe     label1
        nop
label1:

habran

This is written in MASM Programmer's Guide:

Instruction Jumps if
JC/JB/JNAE   Carry flag is set
JNC/JNB/JAE Carry flag is clear
JBE/JNA        Either carry or zero flag is set
JA/JNBE        Carry and zero flag are clear
JE/JZ            Zero flag is set
JNE/JNZ        Zero flag is clear
JL/JNGE        Sign flag != overflow flag
JGE/JNL        Sign flag = overflow flag
JLE/JNG        Zero flag is set or sign != overflow
JG/JNLE        Zero flag is clear and sign = overflow
JS                Sign flag is set
JNS              Sign flag is clear
JO                Overflow flag is set
JNO              Overflow flag is clear
JP/JPE           Parity flag is set (even parity)
JNP/JPO        Parity flag is clear (odd parity)

I can make this happen in JWasm:
ZRORCRY?      jbe
!ZRORCRY?     ja

and instead of  SZERO?   and !SZERO? :


SZRORCRY?      jle
!SZRORCRY?     jg

Cod-Father

habran

here you are:

    mov eax,ptScale.x
000000013FB211F1 8B 84 24 90 00 00 00 mov         eax,dword ptr [ptScale] 
    and eax, 8000000fH
000000013FB211F8 25 0F 00 00 80       and         eax,8000000Fh 
    .if (SZRORCRY? )
000000013FB211FD 7E 07                jle         main+47h (013FB21206h) 
      dec eax
000000013FB211FF FF C8                dec         eax 
      or eax, -16
000000013FB21201 83 C8 F0             or          eax,0FFFFFFF0h 
      inc eax
000000013FB21204 FF C0                inc         eax 
    .endif
    add ptScale.x, eax
000000013FB21206 01 84 24 90 00 00 00 add         dword ptr [ptScale],eax 

    mov ecx, eax
000000013FB2120D 8B C8                mov         ecx,eax 
    and ecx, 8000000fH
000000013FB2120F 81 E1 0F 00 00 80    and         ecx,8000000Fh 
    .if (!SZRORCRY? )
000000013FB21215 7F 07                jg          main+5Fh (013FB2121Eh) 
    dec ecx
000000013FB21217 FF C9                dec         ecx 
    or ecx, -16
000000013FB21219 83 C9 F0             or          ecx,0FFFFFFF0h 
    inc ecx
000000013FB2121C FF C1                inc         ecx 
    .endif
    add eax, ecx
000000013FB2121E 03 C1                add         eax,ecx 
    mov eax, 16
000000013FB21220 B8 10 00 00 00       mov         eax,10h 
    mov ecx, eax
000000013FB21225 8B C8                mov         ecx,eax 
    and ecx, 8000000fH
000000013FB21227 81 E1 0F 00 00 80    and         ecx,8000000Fh 
    .if (!ZRORCRY? )
000000013FB2122D 77 07                ja          main+77h (013FB21236h) 
    dec ecx
000000013FB2122F FF C9                dec         ecx 
    or ecx, -16
000000013FB21231 83 C9 F0             or          ecx,0FFFFFFF0h 
    inc ecx
000000013FB21234 FF C1                inc         ecx 
    .endif
    add eax, ecx
000000013FB21236 03 C1                add         eax,ecx 
   
    mov ecx, eax
000000013FB21238 8B C8                mov         ecx,eax 
    and ecx, 8000000fH
000000013FB2123A 81 E1 0F 00 00 80    and         ecx,8000000Fh 
    .if (ZRORCRY?)
000000013FB21240 76 07                jbe         main+8Ah (013FB21249h) 
    dec ecx
000000013FB21242 FF C9                dec         ecx 
    or ecx, -16
000000013FB21244 83 C9 F0             or          ecx,0FFFFFFF0h 
    inc ecx
000000013FB21247 FF C1                inc         ecx 
    .endif
    add eax, ecx
000000013FB21249 03 C1                add         eax,ecx 

Cod-Father

habran

if you can come with more clear notation I'll be happy to accept it
all I need is to have  JG, JGE, JL, JLE, JA, JBE  branches  without using CMP, TST, OR, AND
Cod-Father

dedndave

no - i see what you are trying to do - and it's good
there have been many times when i go back to the old branch label method to get what i want
sometimes because of the lack of Jcc support - sometimes due to complex branch construction

i can't state my case any clearer, i guess - lol
my thinking was that - one of the goals is to have JwAsm compatible with Masm
so - if i write a program for one, it should assemble with the other - minimal modification required
i don't know if that is really one of Andreas' primary goals or not

habran

JWasm CAN do anything what MASM can do but MASM is just a little brother to grown up JWasm
Why would we need a backward compatibility? There would be no point to develop it
JWasm is flexible and getting better and better   

I can not go back to MASM it would be the same as trying to wear shoes from my childhood :bgrin:

I found somewhere on this forum that jj2007  also pointed out these missing flags

IMO we can not let C or C++ or any other HLL to be more capable than ASM
there would be no point to do programming in ASM
That is why, when ever I stumble on something missing or not good enough in JWasm I try to make it better
(fortunately that source code is available)
remember THE BEATLES Lyrics:"Take a sad song and make it better" :biggrin:
Cod-Father

habran

I can change SCARRY?  to SIGNEQUO? and !SCARRY? to !SIGNEQUO?
than we would have 6 new jumps:
Instruction Jumps if:
SIGNEQUO?     jge  Sign flag = overflow flag
!SIGNEQUO?    jl     Sign flag != overflow flag
SZRORCRY?     jle    Zero flag is set or sign != overflow
!SZRORCRY?    jg     Zero flag is clear and sign = overflow
ZERORCRY?     jbe    Either carry or zero flag is set
!ZERORCRY?    ja     Carry and zero flag are clear
Cod-Father

dedndave

the names you assign aren't critical - i would try to use something readable

Unsigned
JA           Jump if above             CF=0 and ZF=0
JBE          Jump if below or equal    CF=1 or ZF=1


Signed
JG           Jump if greater           SF=OF or ZF=0
JGE          Jump if greater or equal  SF=OF
JL           Jump if less              SF<>OF
JLE          Jump if less or equal     SF<>OF or ZF=1


for unsigned, ABOVE? should do the job
JA    !ABOVE?
JBE   ABOVE?


for signed, LESS? and GREATER?
JG    !GREATER?
JGE   LESS?
JL    !LESS?
JLE   GREATER?


notice that you branch if the case is false, so they seem backwards   :P
    .if A !GREATER? B
        ;do some code
    .endif

the branch is used to jump around the code, so a JG instruction is used in that case

GREATERTHAN and LESSTHAN would also be good choices

still, the info i posted in reply #7 is valid - i.e., both could be supported
go back and read that reply again - if it is not clear to you, i will try to make 6 code examples