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

daydreamer

Quote from: jj2007 on May 25, 2024, 11:18:08 PM
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.
You can use movd xmm0,eax so you can use sse2 instruction set for byte,word,dword sized branchless cmp
Result in 0 or 0ffffffffh mask you can use for example conditional add
Mov ebx,speed
And ebx,mask
Add edx,ebx
Similar thinking in basic
X=x+(inkey=right arrow)*speed

Neg = not eax
Inc eax
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

NoCforMe

Quote from: HSE on May 26, 2024, 04:09:49 AMMore easy:

and ax, 7FFFh
Dang.
I didn't believe you. Then I coded up a li'l testbed. It works.
So why do people use that more complicated method that I posted when all you got to do is get rid of the high bit?
Are there any corner cases where this doesn't work?

Yes; it doesn't work.
[e:\programming stuff\assembly language\windows\snippets]abstest
abs(-832) = 2147482816     - WRONG
abs(832) = 832
abs(-1) = 2147483647       - WRONG
abs(-2147483648) = 0       - WRONG

(last value was 80000000h (32-bit test))

So there's a reason to use the more complex one.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Well, my method works. Sort of:
[e:\programming stuff\assembly language\windows\snippets]abstest
abs(-832) = 832
abs(832) = 832
abs(-1) = 1
abs(-2147483648) = -2147483648
Last value tested was 80000000h. Why didn't that work?
I'm using wsprintf() to display everything. Format string is
ResultFmt        DB "abs(%d) = %d", $CRLF, 0
%d shows a DWORD as a signed value, right?

So [dumb question]: what is the (signed decimal) value of 80000000h? Or is that not a valid twos-complement number?
Assembly language programming should be fun. That's why I do it.

tda0626

Guess there are many ways to do this and appreciate the examples. Came along this one at Stack Overflow:


AT&T syntax


movl  -8(%rbp), %eax    # -8(%rbp) is memory for x on stack
  sarl  $31, %eax         #  shift arithmetic right: x >> 31, eax now represents y
  movl  %eax, %edx        # 
  xorl  -8(%rbp), %edx    #  %edx = x XOR y
  movl  %edx, -4(%rbp)    # -4(%rbp) is memory for output on stack
  subl  %eax, -4(%rbp)    # (x XOR y) - y

NoCforMe

OK, the answer is (drumroll, please):
Quote0x80000000 is + 2,147,483,648 which doesn't fit in a 32-bit signed int but does in a 32-bit unsigned int

Another blind spot of mine; I still have problems wrapping my head around twos-complement arithmetic.

So the largest 32-bit signed value is 7FFFFFFFh (2147483647). But what is the smallest (negative) value)?

Testbed program gives the answer: it's 80000001h (-2147483647). OK, good to know.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: tda0626 on May 26, 2024, 05:13:54 AMGuess there are many ways to do this and appreciate the examples. Came along this one at Stack Overflow:
movl  -8(%rbp), %eax    # -8(%rbp) is memory for x on stack
  sarl  $31, %eax         #  shift arithmetic right: x >> 31, eax now represents y
  movl  %eax, %edx        # 
  xorl  -8(%rbp), %edx    #  %edx = x XOR y
  movl  %edx, -4(%rbp)    # -4(%rbp) is memory for output on stack
  subl  %eax, -4(%rbp)    # (x XOR y) - y
If you check, this is just a (needlessly) more complex version of what I posted above.
Assembly language programming should be fun. That's why I do it.

tda0626

Quote from: NoCforMe on May 26, 2024, 05:19:10 AM
Quote from: tda0626 on May 26, 2024, 05:13:54 AMGuess there are many ways to do this and appreciate the examples. Came along this one at Stack Overflow:
movl  -8(%rbp), %eax    # -8(%rbp) is memory for x on stack
  sarl  $31, %eax         #  shift arithmetic right: x >> 31, eax now represents y
  movl  %eax, %edx        # 
  xorl  -8(%rbp), %edx    #  %edx = x XOR y
  movl  %edx, -4(%rbp)    # -4(%rbp) is memory for output on stack
  subl  %eax, -4(%rbp)    # (x XOR y) - y
If you check, this is just a (needlessly) more complex version of what I posted above.


Ok good to know.

HSE

Quote from: NoCforMe on May 26, 2024, 04:53:21 AMYes; it doesn't work.

:eusa_clap:

The probability to have same error in test was close to 0, I was a little worried  :biggrin:
Equations in Assembly: SmplMath