flat assembler
Message board for the users of flat assembler.

 Index > Main > Logic operators in expression evaluation
Author
geekbasic@gmx.com

Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 19 Nov 2022, 19:45
Currently, I'm working on adding expression parsing to my compiler.
So far, I have support for the basic +, -, *, /, (, and ). I am using push/pop for the evaluation stack. My code is based on RPN.

I'm aware that logic conditions are performed with cmps and jmps, but using that to evaluate an expression would not be optimal. What I need to use is and, or, xor, etc. The problem is I don't know how to do the =, >, <, >=, <=, and <>.

From what I understand, I can use the following for =

Code:
```mov ax,[operand1]
xor ax,[operand2]
not ax
```

and for <> I can use simply

Code:
```mov ax,[operand1]
xor ax,[operand2]
```

So,
if operand1=operand2 then ax is set to 1 if true and 0 if false
if operand1<>operand2 then ax is set to 1 if true and 0 if false.

Ax is pushed to the evaluation stack.

Is this correct? Is there a better way? If so, what is the method for >, <, >=, and <=. I am reading my sources and cannot find the answer to this.[/code]
19 Nov 2022, 19:45
macomics

Joined: 26 Jan 2021
Posts: 921
Location: Russia
macomics 19 Nov 2022, 20:50
Code:
``` ; Starting with Pentium (i586)

; if op1 == op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setz al ; fl.zf == 1

; if op1 <> op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setnz al ; fl.zf == 0

; unsigned integer

; if op1 > op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
seta al ; fl.zf == 0 && fl.cf == 0

; if op1 >= op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setae al ; cf = 0

; if op1 <= op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setbe al ; fl.zf == 1 || fl.cf == 1

; if op1 < op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setb al ; fl.cf == 1

; signed integer

; if op1 > op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setg al ; fl.zf == 0 || fl.sf == fl.of

; if op1 >= op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setge al ; fl.sf == fl.of

; if op1 <= op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setle al ; fl.zf == 1 || fl.zf <> fl.of

; if op1 < op2 then al = 1 else al = 0
mov ax, [op1]
cmp ax, [op2]
setl al ; fl.zf <> fl.of

; float (single/double/extended)

; if op1 == op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; swr.c3 == 1 && swr.c1 == 0
setz al ; fl.zf == 1

; if op1 <> op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; swr.c3 == 0 && swr.c1 == 0
setnz al ; fl.zf == 0

; if op1 > op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; swr.c3 == swr.c2 == swr.c1 == swr.c0 == 0
seta al ; fl.zf == 0 && fl.cf == 0

; if op1 >= op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; swr.c0 == 0 && swr.c1 == 0
setae al ; cf = 0

; if op1 <= op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; (swr.c3 == 1 || swr.c0 == 1) && swr.c1 == 0
setbe al ; fl.zf == 1 || fl.cf == 1

; if op1 < op2 then al = 1 else al = 0
fld [op1]
fcomip [op2]
; swr.c0 == 1 && swr.c1 == 0
setb al ; fl.cf == 1    ```

Last edited by macomics on 20 Nov 2022, 09:29; edited 2 times in total
19 Nov 2022, 20:50
geekbasic@gmx.com

Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 19 Nov 2022, 23:14
Thank you! Now I can grab my asm books and study those functions. If they are even covered in my books. They are from the 80s. Maybe I will need a newer book.

These will only work on a 586? What is the equivalent for 286 or 386? Is it much harder or just less effective?

I just found this site explaining the instructions you have provided me. http://www.mathemainzel.info/files/x86asmref.html#setb
It says they work on a 386. Is it 586 or 386?
19 Nov 2022, 23:14
geekbasic@gmx.com

Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 20 Nov 2022, 07:04
setnae didn't work for the >=
Instead I was able to use setae
20 Nov 2022, 07:04
sts-q

Joined: 29 Nov 2018
Posts: 57
sts-q 20 Nov 2022, 07:18
From macomics post i learned about this setcc instruction. It works on my i3-550 and should go on all other amd/intel x86(_64), too.

Looks like setcc works only with byte or word registers, at least in 64-bit-mode.
I didn't know there is a r10b register, but there is!
Anyway i want the whole r10 register set to 0 or to 1.
(Looked like it is faster, too, but i don't guarantee on that.)

That's why i stay with:

Code:
```
cmp r1, r1         ; compare: set flags
mov rax, 1         ; don't change flags between cmp and cmovxx
mov r1, 0          ; set result := false
cmovl r1,rax       ; conditional move: move only if lesser:  set result := true
```

https://www.felixcloutier.com/x86/cmovcc
20 Nov 2022, 07:18
bitRAKE

Joined: 21 Jul 2003
Posts: 3976
Location: vpcmipstrm
bitRAKE 20 Nov 2022, 07:29
sts-q wrote:
Anyway i want the whole r10 register set to 0 or to 1.
Code:
```mov r10, 0
setl r10b    ```
Code:
```setl r10b
movzx r10, r10b    ```

... using just the single register.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
20 Nov 2022, 07:29
sts-q

Joined: 29 Nov 2018
Posts: 57
sts-q 20 Nov 2022, 07:41

(Thanks!)
20 Nov 2022, 07:41
macomics

Joined: 26 Jan 2021
Posts: 921
Location: Russia
macomics 20 Nov 2022, 08:18
geekbasic@gmx.com wrote:
setnae didn't work for the >=
Sorry. My typo. Use setae.

geekbasic@gmx.com wrote:
These will only work on a 586?
The setxx commands appeared on the i486DX2 processor (as I remember), but starting with the Pentium, their presence can not be checked through the flags in the CPUID.

geekbasic@gmx.com wrote:
What is the equivalent for 286 or 386? Is it much harder or just less effective?
This is both more difficult and less effective.
Code:
```mov ax, [op1]
cmp ax, [op2]
sahf ; ah = fl & 255
shl ah, 2 ; ah = xZxxxxxx -> cf = Z
sbb ax, ax ; if op1 == op2 then ax = -1 else ax = 0    ```
If there are no setxx commands, you will need to manually check the flags based on the value read from the fl register. This can be do with the sahf command or via a couple of pushf/pop ax commands.

sts-q wrote:
Code:
```cmp r1, r1         ; compare: set flags
mov rax, 1         ; don't change flags between cmp and cmovxx
mov r1, 0          ; set result := false
cmovl r1,rax       ; conditional move: move only if lesser:  set result := true    ```
r1?

Last edited by macomics on 20 Nov 2022, 08:37; edited 3 times in total
20 Nov 2022, 08:18
geekbasic@gmx.com

Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 20 Nov 2022, 08:28
thank you for explaining
20 Nov 2022, 08:28
macomics

Joined: 26 Jan 2021
Posts: 921
Location: Russia
macomics 20 Nov 2022, 09:31
Added descriptions of flags and logic for checking them to determine conditions so that you can write code without using setxx commands.
20 Nov 2022, 09:31
geekbasic@gmx.com

Joined: 25 Oct 2022
Posts: 71
Location: Arizona
geekbasic@gmx.com 26 Nov 2022, 22:27
Thank you. This information is very important.

I wonder if I should have a compiler option to allow for either method. It would be nice to have a language that compiles for platforms with the simplest requirements.
26 Nov 2022, 22:27
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum