Author Topic: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS  (Read 1205 times)

LiaoMi

  • Member
  • ****
  • Posts: 698
(R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« on: January 03, 2020, 03:45:30 AM »
Hi,

is it possible to make support for the combination of -Dummy Proc Uses (R)EFLAGS- through the internal compilation algorithm, and for compatibility, report that this feature is used only in UASM  :rolleyes:

HSE

  • Member
  • *****
  • Posts: 1379
  • <AMD>< 7-32>
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #1 on: January 03, 2020, 08:27:44 AM »
Hi LoaMi !

Have you tried:
Code: [Select]
ifdef __UASM__
   Dummy Proc Uses EFLAGS
else
   Dummy Proc
endif

LiaoMi

  • Member
  • ****
  • Posts: 698
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #2 on: January 03, 2020, 09:10:04 AM »
Hi LoaMi !

Have you tried:
Code: [Select]
ifdef __UASM__
   Dummy Proc Uses EFLAGS
else
   Dummy Proc
endif

Hi HSE,

I think this option is not supported at all  :undecided:
main.asm(60) : Error A2210: Syntax error: Uses RFLAGS

jj2007

  • Member
  • *****
  • Posts: 10548
  • Assembler is fun ;-)
    • MasmBasic
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #3 on: January 03, 2020, 02:07:44 PM »
I really wonder why you need an assembler "feature" for such crap. It's a macro assembler, folks...

Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32
include usesFlags.inc

.code

test1 proc arg1, arg2
  usesFlags
  mov eax, arg1
  dec eax ; 123-1=?
  usesFlags
  ret
test1 endp

test2 proc arg1
  usesFlags
  mov eax, arg1
  dec eax ; 123-1=?
  usesFlags
  ret
test2 endp

start:
  xor ebx, ebx ; set the zero flag
  invoke test1, 123, 456
  .if Zero?
print "the usesFlags macro worked fine"
  .else
print "bad luck, it didn't work"
  .endif
  dec ebx ; set the sign flag
  invoke test2, 123
  .if Sign?
MsgBox 0, "the usesFlags macro worked fine", "Hi", MB_OK
  .else
MsgBox 0, "bad luck, it didn't work", "Hi", MB_OK
  .endif
  exit

end start

HSE

  • Member
  • *****
  • Posts: 1379
  • <AMD>< 7-32>
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #4 on: January 03, 2020, 11:36:13 PM »
Quote
ufCount=ufCount and 1

Very clever  :thumbsup:

johnsa

  • Member
  • ****
  • Posts: 807
    • Uasm
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #5 on: January 04, 2020, 02:18:51 AM »
On a related to note to this, there is a PR change coming into UASM 2.50+ to change the epilogue in 64bits so it doesn't trash the flags. As it stands right now you can't return flags as the stack correction will affect flags.

LiaoMi

  • Member
  • ****
  • Posts: 698
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #6 on: January 05, 2020, 03:42:48 AM »
I really wonder why you need an assembler "feature" for such crap. It's a macro assembler, folks...

Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32
include usesFlags.inc

.code

test1 proc arg1, arg2
  usesFlags
  mov eax, arg1
  dec eax ; 123-1=?
  usesFlags
  ret
test1 endp

test2 proc arg1
  usesFlags
  mov eax, arg1
  dec eax ; 123-1=?
  usesFlags
  ret
test2 endp

start:
  xor ebx, ebx ; set the zero flag
  invoke test1, 123, 456
  .if Zero?
print "the usesFlags macro worked fine"
  .else
print "bad luck, it didn't work"
  .endif
  dec ebx ; set the sign flag
  invoke test2, 123
  .if Sign?
MsgBox 0, "the usesFlags macro worked fine", "Hi", MB_OK
  .else
MsgBox 0, "bad luck, it didn't work", "Hi", MB_OK
  .endif
  exit

end start

Hi jj2007,

Quote
It's a macro assembler, folks...
:biggrin:  I knew about macros, one fine winter evening wanted aesthetics - Saving Status register when calling a function - https://stackoverflow.com/questions/48146499/saving-status-register-when-calling-a-function - http://www.c-jump.com/CIS77/samples/IO.htm

This code would look simpler  :azn:
Code: [Select]
itoaproc    PROC   NEAR32
            push   ebp                  ; save base pointer
            mov    ebp, esp             ; establish stack frame
            push   eax                  ; Save registers
            push   ebx                  ;   used by
            push   ecx                  ;   procedure
            push   edx
            push   edi
            pushf                      ; save flags

 Thank you!  :thumbsup:



On a related to note to this, there is a PR change coming into UASM 2.50+ to change the epilogue in 64bits so it doesn't trash the flags. As it stands right now you can't return flags as the stack correction will affect flags.

Hi johnsa,

I did not think about it .. cool  :rolleyes:,we are waiting for a new update  :thumbsup:

jj2007

  • Member
  • *****
  • Posts: 10548
  • Assembler is fun ;-)
    • MasmBasic
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #7 on: January 05, 2020, 09:03:01 AM »
Saving Status register when calling a function - https://stackoverflow.com/questions/48146499/saving-status-register-when-calling-a-function

Most important phrase from that article: Nobody saves it, except in very rare cases

If you have such a rare case, use
Code: [Select]
pushf   ; explain why
invoke somealgo, 123, 456
popf

AW

  • Member
  • *****
  • Posts: 2583
  • Let's Make ASM Great Again!
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #8 on: January 05, 2020, 10:53:45 PM »
pushf only pushes 2 bytes, not 4 as most people believe. To push 4 bytes we have to use pushfd.
Other than this I am convinced that either using macros or automating the assembler around these little things is an absolute waste of time (and, of course, we can always find ways for such automation/macros break and fail to fulfill its mission) that could be better invested to fix little bugs here and there.  :icon_idea:

jj2007

  • Member
  • *****
  • Posts: 10548
  • Assembler is fun ;-)
    • MasmBasic
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #9 on: January 05, 2020, 11:39:17 PM »
Right  :thumbsup:

I checked and found only two occurrences of pushfd/popfd in all my sources. It is so rarely used nowadays that implementing a uses flags in the assembler itself is really a waste of time. Besides, the code is more readable with
pushfd
invoke somestuff
popfd

Note, though, that in the old days of DOS, most 21h interrupts returned the carry flag set in case of error. But that is history :cool:

LiaoMi

  • Member
  • ****
  • Posts: 698
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #10 on: January 06, 2020, 01:30:33 AM »
Saving Status register when calling a function - https://stackoverflow.com/questions/48146499/saving-status-register-when-calling-a-function

Most important phrase from that article: Nobody saves it, except in very rare cases

If you have such a rare case, use
Code: [Select]
pushf   ; explain why
invoke somealgo, 123, 456
popf

Hi jj2007,

this is a matter of clarity, you can always write differently, I just suggested a probable opportunity, which, as I understand it, exists in some compilers. I do not pretend for any better implementation. In programs with complex embedded logic, such as interpreters, which can have two or three nested contexts, this is very convenient, but this is only my opinion. This is also convenient for writing drivers. :skrewy:

Execution without USES
Code: [Select]
.data
;align 8
_COA struct
Val3 WORD 0
Val4 ULONG 0
Val5 WORD 0
Val6 ULONG 0
_COA ends

Val1 USHORT 0
Val2 ULONG 0
Val3 qword 6

_REG struct
reg_rflags     qword 246
reg_rdx         qword 0
reg_rax         qword -50000
_REG ends

COA _COA <?>
REGeflagsEdx _REG <246,0,-50000>

COAsz equ sizeof COA
ValX qword 0ddddddddddddddddh

.code
align 16
mainCRTStartup proc PUBLIC Uses rcx
    mov rbx,COAsz
    mov Val1,1
    mov Val2,2
   
    cmp Val3, 511;
    call Dummy1
    jbe notequal1
    nop
    nop
    nop
    notequal1:
    mov rbx, 256
    cmp Val3, 6
    call Dummy2IdivDword
    jnge equal2
    assume rax:ptr _COA
    lea rax, COA
    mov [rax].Val3, 5
    mov [rax].Val4, 6
    mov [rax].Val5, 7
    mov [rax].Val6, 8
   
    equal2:
   
    ret
mainCRTStartup endp

Dummy1 proc
    ;PUSHFQ
    sub eax, ebx ; = a-b
    sbb edx, edx ; = (b > a) ? 0xFFFFFFFF : 0
    and edx, eax ; = (b > a) ? a-b : 0
    add ebx, edx ; Result is in ebx
    ;popfq
    ret
Dummy1 endp

Dummy2IdivDword proc
;pushfq
push rbx

assume rdi:ptr _REG
    lea rdi, REGeflagsEdx

mov rdx,[rdi].reg_rdx
test edx, 80000000h
jz idiv_dword_edx_pos
;
neg rdx

idiv_dword_edx_pos:
test ebx,80000000h
jz idiv_dword_ebx_pos
;
neg rbx

idiv_dword_ebx_pos:
cmp rdx,rbx
jae DivFault
;
pop rbx
mov ah,byte ptr [rdi].reg_rflags
sahf
mov rax,[rdi].reg_rax
mov rdx,[rdi].reg_rdx
idiv rbx
mov rcx,rax
lahf
mov byte ptr [rdi].reg_rflags,ah
mov [rdi].reg_rax,rcx
mov [rdi].reg_rdx,rdx

    DivFault:
    ;popfq
    ret
Dummy2IdivDword endp

end

Execution with USES
Code: [Select]
.data
;align 8
_COA struct
Val3 WORD 0
Val4 ULONG 0
Val5 WORD 0
Val6 ULONG 0
_COA ends

Val1 USHORT 0
Val2 ULONG 0
Val3 qword 6

_REG struct
reg_rflags     qword 246
reg_rdx         qword 0
reg_rax         qword -50000
_REG ends

COA _COA <?>
REGeflagsEdx _REG <246,0,-50000>

COAsz equ sizeof COA
ValX qword 0ddddddddddddddddh

.code
align 16
mainCRTStartup proc PUBLIC Uses rcx
    mov rbx,COAsz
    mov Val1,1
    mov Val2,2
   
    cmp Val3, 511;
    call Dummy1
    jbe notequal1
    nop
    nop
    nop
    notequal1:
    mov rbx, 256
    cmp Val3, 6
    call Dummy2IdivDword
    jnge equal2
    assume rax:ptr _COA
    lea rax, COA
    mov [rax].Val3, 5
    mov [rax].Val4, 6
    mov [rax].Val5, 7
    mov [rax].Val6, 8
   
    equal2:
   
    ret
mainCRTStartup endp

Dummy1 proc
    PUSHFQ
    sub eax, ebx ; = a-b
    sbb edx, edx ; = (b > a) ? 0xFFFFFFFF : 0
    and edx, eax ; = (b > a) ? a-b : 0
    add ebx, edx ; Result is in ebx
    popfq
    ret
Dummy1 endp

Dummy2IdivDword proc
pushfq
push rbx

assume rdi:ptr _REG
    lea rdi, REGeflagsEdx

mov rdx,[rdi].reg_rdx
test edx, 80000000h
jz idiv_dword_edx_pos
;
neg rdx

idiv_dword_edx_pos:
test ebx,80000000h
jz idiv_dword_ebx_pos
;
neg rbx

idiv_dword_ebx_pos:
cmp rdx,rbx
jae DivFault
;
pop rbx
mov ah,byte ptr [rdi].reg_rflags
sahf
mov rax,[rdi].reg_rax
mov rdx,[rdi].reg_rdx
idiv rbx
mov rcx,rax
lahf
mov byte ptr [rdi].reg_rflags,ah
mov [rdi].reg_rax,rcx
mov [rdi].reg_rdx,rdx

    DivFault:
    popfq
    ret
Dummy2IdivDword endp

end

jimg

  • Member
  • ***
  • Posts: 463
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #11 on: January 06, 2020, 01:33:06 AM »
It may be history, but I still use the carry flag to indicate an error in my own routines  :wink2:

daydreamer

  • Member
  • *****
  • Posts: 1360
  • building nextdoor
Re: (R)EFLAGS Register - PUSHF/PUSHFD/PUSHFQ - Proc Uses (R)EFLAGS
« Reply #12 on: February 09, 2020, 09:15:30 PM »
Right  :thumbsup:

I checked and found only two occurrences of pushfd/popfd in all my sources. It is so rarely used nowadays that implementing a uses flags in the assembler itself is really a waste of time. Besides, the code is more readable with
pushfd
invoke somestuff
popfd

Note, though, that in the old days of DOS, most 21h interrupts returned the carry flag set in case of error. But that is history :cool:
one reason would be code a IF (condition) and (condition) and (condition) and (Condition)....
in a chess engine that goes up and down in a tree ,recursive proc calling itself,so in the end pops all conditions into register and makes use of AND's and final jump on zero flag
Quote from Flashdance
Nick  :  When you give up your dream, you die
*wears a flameproof asbestos suit*
Gone serverside programming p:  :D
I love assembly,because its legal to write
princess:lea eax,luke
:)