News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

.IF Statement

Started by tda0626, May 25, 2024, 04:06:09 AM

Previous topic - Next topic

tda0626

I want to test for a negative number so I can convert to an absolute value but would like to not use a conditional like below or jump. How would I do that?
edited for clarification...
; Check for a negative number
.if ax & 08000h
     neg ax
.endif


Tim

Vortex

Hello,

You can check the most significant bit of ax :

include    \masm32\include\masm32rt.inc

.data

msg1        db 'Postive',0
msg2        db 'Negative',0

.code

start:

    mov   ax,-9
    test  ax,8000h
    jnz   NegResult

    invoke  StdOut,ADDR msg1
    jmp    _exit

NegResult:

    invoke  StdOut,ADDR msg2
   
_exit:

    invoke  ExitProcess,0

END start

QuoteIn the x86 assembly language, the TEST instruction performs a bitwise AND on two operands. The flags SF, ZF, PF are modified while the result of the AND is discarded. The OF and CF flags are set to 0, while AF flag is undefined.

https://en.wikipedia.org/wiki/TEST_(x86_instruction)

NoCforMe

Well, Vortex, the correct (and simplest) answer to the OP's question would have been "yes":
.if ax & 08000h
    neg ax
.endif
does the same thing as TEST (which as you pointed out is a non-destructive AND).

Assembly language programming should be fun. That's why I do it.

tda0626

I want to do it without branching.

What about this?

.if ax > 08000h
add ax, 1        ; add 1 since we get a 1s compliment from below
.endif
mov bx, ax
sar bx, 15
xor ax, bx

NoCforMe

Quote from: tda0626 on May 25, 2024, 05:32:07 AMI want to do it without branching.

What about this?
.if ax > 08000h
        add ax, 1        ; add 1 since we get a 1s compliment from below
    .endif
Well, that's a branch right there.
(1s complement)
Assembly language programming should be fun. That's why I do it.

jj2007

The shortest (and usually fastest) version:

test ax, ax
.if Sign?
   ...

daydreamer

Quote from: tda0626 on May 25, 2024, 05:32:07 AMI want to do it without branching.

What about this?

.if ax > 08000h
        add ax, 1        ; add 1 since we get a 1s compliment from below
    .endif
    mov bx, ax
    sar bx, 15
    xor ax, bx
Check replace j** with set** after cmp or test
Set** sets a register to 1 or 0 depending on cmp result instead  j**
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on May 25, 2024, 07:04:38 PMSet** sets a register to 1 or 0 depending on cmp result

That is correct, and I've used the "branchless" set* instruction sometimes. However, it's quite limited, as a) it sets the byte, not the DWORD, i.e. al, not eax, and b) you get only 0 or 1. If that is sufficient, perfect.

sinsi

Quote from: tda0626 on May 25, 2024, 04:06:09 AMI want to test for a negative number and can't seem to find any documentation on it but was wondering if this was ok.

; Check for a negative number
.if ax & 08000h
     neg ax
.endif


Tim

  mov dx,ax
  neg dx
  bt ax,15
  cmovc ax,dx

HSE

Hi all!

So far I understand, branchless means that you don't use any conditional instruction.

See code:
include    \masm32\include\masm32rt.inc

.data
    msg1        db 'Postive',0
    msg2        db 'Negative',0
    table  dd offset msg1
           dd offset msg2
.code

start:
    mov eax,  0
    mov  ax, -9        ; value to test
    shr  ax, 15

    lea edx, table
    mov ecx, [edx+eax*4]

    print ecx, 13,10

    inkey

    invoke  ExitProcess,0

END start

In this case I used Vortex example. But usually table contains address to jump.

Regards, HSE.
Equations in Assembly: SmplMath

sinsi

I figured branchless = no jumps

NoCforMe

Quote from: sinsi on May 26, 2024, 02:02:11 AMI figured branchless = no jumps
Correctamundo.

I believe this is the canonical easiest way to implement a branch-less abs(), which is what the OP is after (16-bit version):
  CWD               ;Sign-extend AX to DX:AX
  XOR  AX, DX
  SUB  AX, DX
Assembly language programming should be fun. That's why I do it.

sinsi

Couldn't see the forest for the trees, was blinded by the question and didn't follow the code.

Did you mean CWD?

NoCforMe

Whoops, yeah: should be
  CWD              ;Sign-extend AX to DX:AX
  XOR  AX, DX
  SUB  AX, DX
Assembly language programming should be fun. That's why I do it.

HSE

Quote from: NoCforMe on May 26, 2024, 03:06:57 AMI believe this is the canonical easiest way to implement a branch-less abs(), which is what the OP is after (16-bit version):
  CBW              ;Sign-extend AX to DX:AX
  XOR  AX, DX
  SUB  AX, DX

:biggrin:

More easy:

and ax, 7FFFh
Equations in Assembly: SmplMath