flat assembler
Message board for the users of flat assembler.
Index
> Main > Strange Warning |
Author |
|
sinsi 07 Jan 2010, 03:37
Maybe because a conditional jump is usually a signed byte relative to IP?
That is one reason older 16-bit code had 'jump islands' for when a jump was too far. |
|||
07 Jan 2010, 03:37 |
|
DOS386 07 Jan 2010, 14:03
Quote:
And the error is ??? Code: jz word [bp] ; This is NOT valid since conditional jumps accept only jz near [bp] ; constant relative to IP (only 8 bit 8086, also 16 or 32 bits since 80386) better 8086-compatible way: Code: jnz short @f jmp near [bp] @@: EDIT : fixed BUG pointed below, see below for better solutions Last edited by DOS386 on 08 Jan 2010, 08:42; edited 1 time in total |
|||
07 Jan 2010, 14:03 |
|
LocoDelAssembly 07 Jan 2010, 17:00
It won't work even on Core i7, as sinsi said, conditional jump instructions only accept relative operand (the assembler transforms a label reference or a number into a number relative to ({R,E})IP.
|
|||
07 Jan 2010, 17:00 |
|
bitshifter 08 Jan 2010, 05:39
I was unaware of that, thanks for the tips
So does anyone have an idea on how to improve this algorithm? I thought about length prefixing so i could rep cmpsb... Maybe you have an interesting idea or better approach? |
|||
08 Jan 2010, 05:39 |
|
edfed 08 Jan 2010, 05:48
Code: mov bp,handler ... jz .call ... .call: call near[bp] |
|||
08 Jan 2010, 05:48 |
|
bitshifter 08 Jan 2010, 05:51
I cant use call since each handler jmp's back into the main loop.
Im trying to keep is small and fast at the same time... |
|||
08 Jan 2010, 05:51 |
|
LocoDelAssembly 08 Jan 2010, 06:42
WARNING: Completely untested
Code: g_Commands: db 4, 'HELP', OnHelp db 3, 'VER', OnVer db 4, 'DATE', OnDate db 4, 'TIME', OnTime db 3, 'DIR', OnDir db 3, 'CLS', OnCls db 6, 'REBOOT', OnReboot db 0 . . . .on_cmd: mov si, g_Commands - 2 xor cx, cx .compare: add si, cx add si, 2 lodsb test al, al jnz .not_cmd mov cl, al repe cmpsb jne .compare jmp word [si] .not_cmd: . . . |
|||
08 Jan 2010, 06:42 |
|
bitshifter 08 Jan 2010, 07:46
I never thought of merging the strings and handlers, great idea!
Its so much easier to look at it that way. My goal is to have an easy way to add new functionality. |
|||
08 Jan 2010, 07:46 |
|
sinsi 08 Jan 2010, 08:10
Just a small note about the original code - accessing [bp] uses the SS segment, not DS, so word[bp] is actually word[ss:bp].
If ss <> ds you will run into problems. |
|||
08 Jan 2010, 08:10 |
|
bitshifter 08 Jan 2010, 08:46
Thanks sinsi
Ok, after some changes, Loco's code now works... First, fasm was complaining about size's so i changed the command table to... Code: g_Commands: db 4,'HELP' dw OnHelp db 3,'VER' dw OnVer db 4,'DATE' dw OnDate db 4,'TIME' dw OnTime db 3,'DIR' dw OnDir db 3,'CLS' dw OnCls db 6,'REBOOT' dw OnReboot db 0 Then the DI register was getting trashed by cmpsb so i fixed that. And also the code allowed HELP*** to be legal so i fixed that too. (The command input buffer is NULL terminated after being filled) Code: .on_cmd: mov si,g_Commands - 2 xor cx,cx .compare: add si,cx add si,2 lodsb test al,al jz .NotCmd mov di,g_CmdBuf ; REFRESH DI mov cl,al repe cmpsb jnz .compare ; CHECK ZF INSTEAD cmp byte[di],0 ; VERIFY END OF COMMAND jne .compare jmp word[si] .not_cmd: Its fun exploring the different ways to skin a cat Thanks for your help guys! |
|||
08 Jan 2010, 08:46 |
|
sinsi 08 Jan 2010, 09:02
If you know the length of the input buffer that is another way to skip comparing (if length <> commandlength).
Do you convert your input to upper case? |
|||
08 Jan 2010, 09:02 |
|
bitshifter 08 Jan 2010, 09:09
Yes, it gets converted to UPPERCASE.
But the length is never saved... I acquire input into buffer by DI Then NULL terminate it upon <ENTER> Then to uppercase (in reverse) Then goes to command router... |
|||
08 Jan 2010, 09:09 |
|
LocoDelAssembly 08 Jan 2010, 16:30
bitshifter, jne=jnz.
Code: jne $ jnz $ load a byte from $-4 load b byte from $-2 if a = b display "Same opcode!", 13, 10 else display "Not the same instruction", 13, 10 end if What incredibly stupid mistakes I made there... |
|||
08 Jan 2010, 16:30 |
|
bitshifter 08 Jan 2010, 18:09
I think that by using
Code: rep cmpsb jne .compare We can also eliminate Code: add si,cx And then let cmpsb burn through the whole thing... But this is just an early morning observation... |
|||
08 Jan 2010, 18:09 |
|
LocoDelAssembly 08 Jan 2010, 18:37
Code: rep repe load a byte from $-2 load b byte from $-1 if a = b display "Same opcode!", 13, 10 else display "Not the same instruction", 13, 10 end if |
|||
08 Jan 2010, 18:37 |
|
bitshifter 08 Jan 2010, 18:58
Hmm, although it says they are same opcode
my changes doesnt work like i thought it would Code: rep cmpsb Not same as! Code: repe cmpsb I need some coffee before my brain starts functioning properly... |
|||
08 Jan 2010, 18:58 |
|
LocoDelAssembly 08 Jan 2010, 19:10
Just to be sure I've just tested "rep cmpsb" and "repe cmpsb" and both have the very same opcode+prefix code (F3 A6).
With the same I mean that with REP you won't get the "run until CX is zero" effect but "run until CX is zero or ZF is non-zero (flag checked after comparison)". CMPS accepts REPE (which has the same opcode than REP) and REPNE only. |
|||
08 Jan 2010, 19:10 |
|
DOS386 09 Jan 2010, 02:11
> Strange Warning
> FASM complain about jumping There is no "Strange Warning" at all, just a justified complaint about faulty code. Also FASM IIRC doesn't support warns at all, just errors Also it finds per compilation attempt just one compiler-detectable bug, even if there are more (see shot), and this is not necessarily the earliest bug in the source (see shot, try to comment-out line 12).
|
||||||||||
09 Jan 2010, 02:11 |
|
bitshifter 09 Jan 2010, 04:53
Thanks DOS386
Ok, so now that it works nicely, the next step is to make it more readable, thus we introduce a new macro! So i open the FASM manual and read more about macro's. Then i compile the LISTING.EXE tool included with FASM. Now i can see exactly what FASM is making with my macro. (Good thing, because my first few tries were way off) So in the long run i came up with this macro... Code: macro MESSAGE_MAP command*,handler* { local marker db marker - $ - 1 ; prefixed length db command ; command string marker: dw handler ; command handler } Now i tested its output with LISTING.EXE and all is good So now unreadable code like this... Code: g_Commands: db 4,'HELP' dw OnHelp db 3,'VER' dw OnVer db 4,'DATE' dw OnDate db 4,'TIME' dw OnTime db 3,'DIR' dw OnDir db 3,'CLS' dw OnCls db 6,'REBOOT' dw OnReboot db 0 Now becomes readable once again like this... Code: g_Commands: MESSAGE_MAP 'HELP', OnHelp MESSAGE_MAP 'VER', OnVer MESSAGE_MAP 'DATE', OnDate MESSAGE_MAP 'TIME', OnTime MESSAGE_MAP 'DIR', OnDir MESSAGE_MAP 'CLS', OnCls MESSAGE_MAP 'REBOOT', OnReboot db 0 Ahh, good times, the adventures of coding with FASM |
|||
09 Jan 2010, 04:53 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.