flat assembler
Message board for the users of flat assembler.
![]() Goto page 1, 2 Next |
Author |
|
Overflowz 24 Sep 2011, 20:04
you can do something like this:
Code: mov al,1 test al,al ;ZF = 0 or set to 1. Code: xor al,al ;ZF = 1 or maybe you want to try JZ/JNZ instructions ? |
|||
![]() |
|
Teehee 24 Sep 2011, 20:14
i was looking for an only instruction to do that
![]() Last edited by Teehee on 24 Sep 2011, 20:15; edited 1 time in total |
|||
![]() |
|
Overflowz 24 Sep 2011, 20:15
I haven't seen such thing yet. I saw how to modify flags with PUSHFD and then OR-ing it. I think there's no such way
![]() |
|||
![]() |
|
MHajduk 24 Sep 2011, 20:31
What about this couple of instructions:
Code: lahf btc eax, 14 sahf |
|||
![]() |
|
Teehee 24 Sep 2011, 20:52
MHajduk wrote: What about this couple of instructions: i can do that with 2 instructions: Code: setz al
test al,al i just wanted do that with 1 ![]() |
|||
![]() |
|
MHajduk 24 Sep 2011, 20:53
Another possibility:
Code: setnz al xor al, 1 ![]() |
|||
![]() |
|
MHajduk 24 Sep 2011, 21:10
Teehee wrote: i have a function that return ZF = 0 if true. Code: cmc ; ~ CF (negation of the carry flag) ![]() |
|||
![]() |
|
Teehee 24 Sep 2011, 22:58
i don't know how to work with CF
![]() i do a call to a function that returns me ZF 0 if ok. Then i need to invert this value in order to negate the caller return. see (read comments): Code: is_binary: lodsb cmp al,'0' jb .no cmp al,'1' ja .no @@: lodsb cmp al,'0' je @b cmp al,'1' je @b cmp al,'b' jne .no call is_let_or_num ; if its letter or number (is_let_or_num ZF = 0) sete al ; i need to say its not a valid binary test al,al ; (is_binary ZF = 1) .no: ret ; return ( ZF ) 0 = is binary is_let_or_num: lodsb cmp al,'0' jb .no cmp al,'9' jbe .yes cmp al,'A' jb .no cmp al,'Z' jbe .yes cmp al,'a' jb .no cmp al,'z' jg .no .yes: xor eax,eax .no: ret ; return ( ZF ) 0 = is letter or number _________________ Sorry if bad english. |
|||
![]() |
|
Teehee 24 Sep 2011, 23:42
well, i read the manual and it says XOR clear CF and CMP set CF according to the result. How do i know which results set CF in the CMP instruction?
|
|||
![]() |
|
Teehee 24 Sep 2011, 23:53
anyway i did a test and CMC works like a charm
![]() |
|||
![]() |
|
LocoDelAssembly 25 Sep 2011, 00:11
Code: is_let_or_num: ;Using CF instead of ZF to return result lodsb sub al, '0' cmp al, '9' - '0' + 1 jb .yes sub al, 'A' - '0' cmp al, 'Z' - 'A' + 1 jb .yes sub al, 'a' - 'A' cmp al, 'z' - 'a' + 1 .yes: .no: ret |
|||
![]() |
|
Teehee 25 Sep 2011, 12:44
very skilful LocoDelAssembly
i need to use SUB to activate the CF? or it was just a trick |
|||
![]() |
|
LocoDelAssembly 25 Sep 2011, 15:16
Besides it saves several conditional jumps (which is a good thing), I think it wouldn't be possible otherwise, if "cmp al, '0'" were executed with AL = $0a, it would set the carry flag, so I'd need CMC before returning. So the SUBs are serving a dual purpose, as a well known trick to test if a given number is inside a range, and also as a convenient method to have only the CMPs which set the CF properly.
|
|||
![]() |
|
r22 27 Sep 2011, 18:50
Um why not use a look-up table and TEST
Code: is_let_or_num: MOV dl, -1 LODSB TEST dl, byte[LUT + eax] RET The look-up table will have either a 0 in the location if you want to return ZF = 1 or a 1 in the location if you want the ZF = 0. No branches, no SUB tricks. You just have to build your 256 byte LUT. |
|||
![]() |
|
Teehee 27 Sep 2011, 18:54
oh.. also nice
![]() |
|||
![]() |
|
bitRAKE 27 Sep 2011, 19:00
Of course, there is the bitmap method, too. Only uses 32 bytes of data (single cacheline). Only uses a single register.
Code: xor eax,eax lodsb bt [_alphanum],eax ; carry flag is result ret |
|||
![]() |
|
LocoDelAssembly 27 Sep 2011, 19:17
r22, why using "MOV dl, -1" instead of "TEST byte[LUT + eax], -1"? I mean, it helps on some micro-architectures somehow?
I liked bitRAKE version, and you could also use SBB EAX, EAX to copy CF into ZF if you want to. Teehee, you may want to search the forum for some more variants (I'm almost sure this isalnum-like stuff has been discussed a lot already), my code was just to show you how to adapt your code to use CF. |
|||
![]() |
|
r22 27 Sep 2011, 20:03
LocoDelAssembly wrote: r22, why using "MOV dl, -1" instead of "TEST byte[LUT + eax], -1"? I mean, it helps on some micro-architectures somehow? No reason. |
|||
![]() |
|
edfed 27 Sep 2011, 21:16
bitRAKE wrote: Of course, there is the bitmap method, too. Only uses 32 bytes of data (single cacheline). Only uses a single register. that's exactlly what i wanted to type when i saw you still made it. just to follow: Code: ... lodsb ;would be better to do it in caller no? call islet? jz @f ;no, a letter call printal ;just in case we want to reuse it, for example mov al,[edi] ;and because we can load al from anywhere, in the way we want. call islet? jnz @f ... @@: ... islet?: ;al=char to test ;return zf=1 if letter or num, a num is a letter too. movzx eax,al bt [.lut],eax ret .lut: ;from the font of my bios dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 1111 1111 1100 0000 dw 0111 1111 1111 1111 dw 1111 1111 1110 0000 dw 0111 1111 1111 1111 dw 1111 1111 1110 0000 dw 1111 1111 1111 1111 dw 1111 1111 1111 1111 dw 1111 1100 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 .lut2: ;from the font of my win98 DOS console dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 0000 0000 0000 0000 dw 1111 1111 1100 0000 dw 0111 1111 1111 1111 dw 1111 1111 1110 0000 dw 0111 1111 1111 1111 dw 1111 1111 1110 0000 dw 1111 1111 1111 1111 dw 1111 1111 1110 0000 dw 1111 1100 0000 0000 dw 0000 0111 0000 0000 dw 0000 0011 0000 0000 dw 1111 1011 1000 0010 dw 1111 1111 1111 0100 dw 0000 0000 0000 0000 but it is hard to define what is a letter or not sometimes... $£€éàêëâë, etc...? |
|||
![]() |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.