News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Flag Set

Started by theunknownguy, November 09, 2010, 09:38:38 PM

Previous topic - Next topic

theunknownguy

Simple question guys on my sandbox when i set the flags i can do on 2 methods:

  Set flags via PUSHFD - POPFD (older flags)
  Execute opcode (let the opcode set the flags)
  Save flags via LAHF - SAHF (new flags).


Or

Execute opcode
Set flags manually (doing an jump table for each opcode flag setting)


Adventaje of first method is that i dont need to add each flag specific change for each opcode (wich is a pain in the ass)
Adventaje of second method is that i dont need to use PUSHFD - POPFD - LAHF - SAHF.

So whats best?.

Thanks

PS: If someone know the flag encoding please can tell me? caused i am watching the LAHF opcode and trying to play with the AX 7 first bitfield and cant change flags

dedndave

first, LAHF and SAHF do not contain all the flags
also, in long mode, some processors do not support these instructions

second, SAHF, POPFD or setting flags with instructions like CLD, CLI, etc are all very slow (CLC/STC may be ok)

so, using a table or some other sort of logic seems the best
(i.e., storing the emulated EFLAGS value as a dword variable)
although, it is a lot more work, in terms of programming
in the end, your code will be faster, and you will learn all about the flags   :bg


theunknownguy

Quote from: dedndave on November 10, 2010, 12:50:52 AM
first, LAHF and SAHF do not contain all the flags
also, in long mode, some processors do not support these instructions

second, SAHF, POPFD or setting flags with instructions like CLD, CLI, etc are all very slow (CLC/STC may be ok)

so, using a table or some other sort of logic seems the best
(i.e., storing the emulated EFLAGS value as a dword variable)
although, it is a lot more work, in terms of programming
in the end, your code will be faster, and you will learn all about the flags   :bg



Wow thanks as always for the big help dedndave, seems like i have alot of work to do before doing a test bed hehehe

theunknownguy

Ok dedndave i make your suggestion even if it means alot of work but heres a doubt:

The doubt first is about CF according to the example i read:

255 + 255 = 510
510 (binary) = 1 11111110 (1 bit extra) = CF activated

0 - 1 = 0FFFFFFFF
0FFFFFFFF = 11111111111111111111111111111111 (Lots of bit extra) = CF activated


All of this in a context where the operation was 8bit like ADD AL, CL.

So in order for me to check if its exceed the size of operation i first need to execute the operation on 32bit way (or the max support size). and check if it exceed the real operation size.

Something like this for 8 bit operations:


Mov Eax, Dest       (8 bit)
Mov Edx, Source   (8 bit)
Add Edx, Eax
.If (OperationSize == 8)
   Shr Eax, 8
   .If (Eax > 1)
      Mov FLAGS._CF, 1
   .Else
      Mov FLAGS._CF, 0
   .EndIf
.EndIf


Do i get it ok?

If this is the case then how i do it on 32bit context... I cant make an operation larger than 32 bit for check if it carry...

dedndave

well - you can, in fact
you can use another register to extend the operation to 64 bits, or more to extend it further

mov eax,FirstOperand
xor edx,edx
add eax,SecondOperand
adc edx,0

also - to perform 8 bit flag tests....

mov al,FirstOperand
add al,SecondOperand

the flags now hold correct values
if you recall, i said some instructions are slow
those are the instructions like SAHF, POPFD, CLD, and so on
these instructions set the flags
the instructions that read the flags are not as slow
so, to retrieve the full dword flags...

pushfd
pop eax

is plenty fast

it is when you try to alter the flags...

push eax
popfd

that things are slow

theunknownguy

Quote from: dedndave on November 10, 2010, 10:36:34 PM
well - you can, in fact
you can use another register to extend the operation to 64 bits, or more to extend it further

mov eax,FirstOperand
xor edx,edx
add eax,SecondOperand
adc edx,0

also - to perform 8 bit flag tests....

mov al,FirstOperand
add al,SecondOperand

the flags now hold correct values
if you recall, i said some instructions are slow
those are the instructions like SAHF, POPFD, CLD, and so on
these instructions set the flags
the instructions that read the flags are not as slow
so, to retrieve the full dword flags...

pushfd
pop eax

is plenty fast

it is when you try to alter the flags...

push eax
popfd

that things are slow

god i should make you an honor monument... thanks for the tips but i still want to learn how the flags works (by coding them) and got this problem about OF with CF:

255 + 255 = 510
510 (binary) = 1 11111110 (1 bit extra) = CF activated


This on two complement interpretation of 8bits this is:

-1 (11111111) + -1 (11111111) = -2 (11111110)

And according to the OF description the most significant byte should represent if an overflow happens or not:

[1]1111110

But the overflow never happens, what part of this i dont get...


- The MSB of -1 its 1 representing its negative
- The MSB of 127 its 0 representing its positive
- The MSB of -1 + -1 its 1 (XOR with the previous 1 (MSB of -1)) = 0
- The MSB 127+127 its 1  (XOR with the previous 0 (MSB of 127)) = 1


Do i get it right in there?.  :dance:

FORTRANS

Hi,

   The overflow flag is used with signed arithmetic.  So some
examples.


        MOV     AL,5
        ADD     AL,5    ; 5 + 5 = 10 and no overflow, OF is clear.
                        ; Both 5 and 10 have the high bit clear.
        MOV     AL,127
        ADD     AL,127  ; 127 + 127 should be +254, but as a
                        ; signed number it is actually -2, the 127 has
                        ; a clear high bit and -2 (254) has a set high bit,
                        ; so you overflowed the calculation and OF is set.


Regards,

Steve N.

theunknownguy

Quote from: FORTRANS on November 10, 2010, 10:57:26 PM
Hi,

   The overflow flag is used with signed arithmetic.  So some
examples.


        MOV     AL,5
        ADD     AL,5    ; 5 + 5 = 10 and no overflow, OF is clear.
                        ; Both 5 and 10 have the high bit clear.
        MOV     AL,127
        ADD     AL,127  ; 127 + 127 should be +254, but as a
                        ; signed number it is actually -2, the 127 has
                        ; a clear high bit and -2 (254) has a set high bit,
                        ; so you overflowed the calculation and OF is set.


Regards,

Steve N.

Steve can you check if this code is ok for set the OF:


Mov Eax, Dest       (8 bit)
Mov Edx, Source   (8 bit)
Add Edx, Eax                       ;Trying to get flags from arithmetic ADD (8 bits)
.If (OperationSize == 8)
   Shr Edx, 8                       ;Get the MSB of the Result
   Shr Eax, 8                       ;Get the MSB of the Dest operator
   .If (Edx > 1)
      Mov FLAGS._CF, 1
   .Else
      Mov FLAGS._CF, 0
   .EndIf
   Xor Edx, Eax                      ;XOR both MSB
   Mov FLAGS._OF, Edx          ;Store result
.EndIf


Thanks

-----------------------------------------------------------------------

For dedndave here we go:



PushFD
Pop Eax
Invoke SetFlags, Eax

SetFlags Proc Flags:Dword
Mov Eax, Flags
Mov Ecx, 1
Lea Esi, Offset FLAGS
.Repeat
Mov Edx, Eax
Shr Edx, Cl
And Edx, 1
Mov [Esi+Ecx*4-4], Edx
Add Ecx, 1
.Until (Ecx == 12)
Ret
SetFlags EndP


The PUSHFD seems a good method for saving the flags AFTER emulating an opcode but this is my dilema:

When i execute an emulated opcode save flags, and later flags will be modified by alot of things going under for read the next opcode.
When the time to execute a new opcode comes, it might rely of the older flags, but how i set them back?... Thats my dilema.

Opcode   Instruction   Clocks   Description

9D       POPF          5        Pop top of stack FLAGS
9D       POPFD         5        Pop top of stack into EFLAGS


It uses 5 clocks and i would have to execute it once before emulating an opcode. The benefit i think its pretty much than setting the flags myself + coding each opcode in relation to the previous flags, dont you think?

dedndave

well - that is what i was saying
i am not writing an emulator, so i don't know the best way to handle it   :P

but - one solution that should work, even if it is slow...
        push dword ptr FLAGS
        popfd

then perform your emulated operation

theunknownguy

Quote from: dedndave on November 11, 2010, 01:03:25 AM
well - that is what i was saying
i am not writing an emulator, so i don't know the best way to handle it   :P

but - one solution that should work, even if it is slow...
        push dword ptr FLAGS
        popfd

then perform your emulated operation

Yes its the only method left, rebuilding each opcode for its fuctionallity with a determinated flag + setting flags by manual must exceed 5 clocks for sure...

GetFlags Proc
Lea Esi, Offset FLAGS
Xor Edx, Edx
Mov Ecx, 1
.Repeat
Mov Eax, [Esi+Ecx*4-4]
Shl Edx, 1
Add Edx, Eax
Add Ecx, 1
.Until (Ecx == MAX_FLAGS)
Push Edx
PopFD
GetFlags EndP


Anyway thanks again for all your help, ill do finally a test bed and see if it run slow or fast.  :cheekygreen: