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:
Hi LoaMi !
Have you tried:ifdef __UASM__
Dummy Proc Uses EFLAGS
else
Dummy Proc
endif
Quote from: HSE on January 03, 2020, 08:27:44 AM
Hi LoaMi !
Have you tried: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
I really wonder why you need an assembler "feature" for such crap. It's a macro assembler, folks...
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
QuoteufCount=ufCount and 1
Very clever :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.
Quote from: jj2007 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...
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,
QuoteIt'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 (https://stackoverflow.com/questions/48146499/saving-status-register-when-calling-a-function) - http://www.c-jump.com/CIS77/samples/IO.htm (http://www.c-jump.com/CIS77/samples/IO.htm)
This code would look simpler :azn:
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:
Quote from: johnsa 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.
Hi johnsa,
I did not think about it .. cool :rolleyes:,we are waiting for a new update :thumbsup:
Quote from: LiaoMi on January 05, 2020, 03:42:48 AMSaving Status register when calling a function - https://stackoverflow.com/questions/48146499/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 casesIf you have such a rare case, use
pushf ; explain why
invoke somealgo, 123, 456
popf
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:
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:
Quote from: jj2007 on January 05, 2020, 09:03:01 AM
Quote from: LiaoMi on January 05, 2020, 03:42:48 AMSaving Status register when calling a function - https://stackoverflow.com/questions/48146499/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
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
.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
.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
It may be history, but I still use the carry flag to indicate an error in my own routines :wink2:
Quote from: jj2007 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:
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