flat assembler
Message board for the users of flat assembler.
Index
> Main > fasm 1.67.21 bug not in 1.64? Goto page 1, 2 Next |
Author |
|
DOS386 25 Mar 2007, 11:23
Code: org 20000h mycall edi, f } use16 I don't think this can work. use16 limits code addressing and org to 64 KB. _________________ Bug Nr.: 12345 Title: Hello World program compiles to 100 KB !!! Status: Closed: NOT a Bug |
|||
25 Mar 2007, 11:23 |
|
Tomasz Grysztar 25 Mar 2007, 13:52
Actually it's the opposite - it was the bug of earlier versions of fasm that was fixed recently. With "use16" your jump defaults to 16 bits, and "org 20000h" makes the addresses invalid for 16 bits. If you want to generate 32-bit jumps (with 66h prefix), you need to do it like:
Code: jmp dword f |
|||
25 Mar 2007, 13:52 |
|
lazer1 26 Mar 2007, 14:16
Tomasz Grysztar wrote: Actually it's the opposite - it was the bug of earlier versions of fasm that was fixed recently. With "use16" your jump defaults to 16 bits, and "org 20000h" makes the addresses invalid for 16 bits. If you want to generate 32-bit jumps (with 66h prefix), you need to do it like: this new feature is a total nuisance, the original code functioned just fine, I now have to change every single jmp instruction: jmp, jg, jge, je, etc apart from pedantry what point is there to this? also I cannot change it via redefining the jmps as that will interfere with the 64 bit code, |
|||
26 Mar 2007, 14:16 |
|
lazer1 26 Mar 2007, 14:29
NTOSKRNL_VXE wrote:
"call f" can have only 1 possible meaning, so fasm should really disambiguate automatically as there is a clear disambiguation, I have literally hundreds of jmp and loop statements in my 32 bit code, I either have to do that via earlier versions of fasm or go through endless code changing to dword, |
|||
26 Mar 2007, 14:29 |
|
LocoDelAssembly 26 Mar 2007, 14:36
Quote:
purge the macros when you reach 64-bit code. Sure that the code without address size override worked good? There was some situations where it worked bad but I can't find the damn thread. |
|||
26 Mar 2007, 14:36 |
|
lazer1 26 Mar 2007, 14:41
lazer1 wrote:
if anything this will lead to MORE BUGS if I accidentally put dword in long mode jmps. Not sure but I think "jmp dword label" would be an absolute jmp which wont be relocatable, ALL my long mode code is relocatable, long mode has been designed to be VERY relocatable, |
|||
26 Mar 2007, 14:41 |
|
LocoDelAssembly 26 Mar 2007, 15:06
"jmp label" and "jmp dword label" are both relative so there is no problem. In fact FASM still encodes with rel8 if possible, it only adds the prefix to the instruction. I still can't find the thread but if I remember right the problem is that without the prefix the CPU does "IP = IP + rel" but since the address doesn't fit in 16 bits there is situations where it will not work and for that you need "EIP = EIP + rel" which is done by the address size override prefix.
|
|||
26 Mar 2007, 15:06 |
|
Tomasz Grysztar 26 Mar 2007, 16:17
Yes, LocoDelAssembly, you remember right. The code from first post assembled with 1.64 would be buggy, as it would clear the upper 16 bits of EIP.
fasm doesn't create a 66h/67h prefixed instructions unless clearly told so - this was decided a long time ago, somewhere between the 0.9.x prereleases and the 1.0 (I recall it was perhaps due to some user feedback), the very early versions were for example doing "aggressive" size optimization in 32-bit mode by generating 16-bit conditional jumps (shorter by one byte). But it really was a bad idea and since then fasm always uses the size default for the given mode, unless the size is explicitly specified. |
|||
26 Mar 2007, 16:17 |
|
LocoDelAssembly 26 Mar 2007, 16:36
Quote:
Oh, then I wrote wrong, it is "EIP = (IP + rel) AND $FFFF". Thanks |
|||
26 Mar 2007, 16:36 |
|
lazer1 26 Mar 2007, 16:41
LocoDelAssembly wrote: "jmp label" and "jmp dword label" are both relative so there is no problem. In fact FASM still encodes with rel8 if possible, it only adds the prefix to the instruction. I still can't find the thread but if I remember right the problem is that without the prefix the CPU does "IP = IP + rel" but since the address doesn't fit in 16 bits there is situations where it will not work and for that you need "EIP = EIP + rel" which is done by the address size override prefix. I guess if you have code which is almost 64K in size and you jump to the far end that will cause a problem as relative jumps are signed 15 bit so to speak: eg if you jump from 20000h to 29000h then it will possibly wrongly jump to 20000h + ffff....ff9000h = 19000h ??? ie the problem even happens in 16 bit code as relative jumps are 15 bit in either direction, I have changed the code now but it was painful, most jumps were to local labels so I sped up the changes via query search and replace "." by "dword ." (eg "jge .done" becomes "jge dword .done", but ".done:" MUSTNT be replaced by "dword .done:" ) (most of my calls are done via macro so I only had to change the 1 macro and a few cases where I called directly) |
|||
26 Mar 2007, 16:41 |
|
lazer1 26 Mar 2007, 17:06
LocoDelAssembly wrote:
it did function fine, but I remember having one inexplicable bug, I then completely redid that part of the code, so it is possible that I redid the call with a nearer function, so any problems I probably worked around by rewriting, note that typically there wont be a problem with jmps as jmps tend to be near, my 16 bit code is via 64K aligned subsets, moving between such is done via far calls, |
|||
26 Mar 2007, 17:06 |
|
LocoDelAssembly 26 Mar 2007, 17:16
That jump would be impossible to encode with rel8/rel16, you have no choice other than rel32 but that is a different problem that the one Tomasz says. Suppose you want to jump from $10000 to $10100, then the calculus would be "$10000 + $100 = $10100", BUT since we are not using the adress size override this will happens: "($10000 + $100) AND $FFFF = $100". $100 obviously is not the expected target so here is of mandatory use the address size override.
|
|||
26 Mar 2007, 17:16 |
|
lazer1 26 Mar 2007, 18:06
LocoDelAssembly wrote:
the modified code no longer functions! possibly "call dword f" uses the stack differently from how the earlier fasm did "call f" I am looking at the function arg and return macros to see if I can resolve the problem, luckily I have a backup of the earlier code, so I could quit the "dword f" idea and just use the earlier fasm for the 16 bit code, |
|||
26 Mar 2007, 18:06 |
|
lazer1 26 Mar 2007, 18:28
what is the correct way to return from a function called via "call dword f" ?
|
|||
26 Mar 2007, 18:28 |
|
lazer1 26 Mar 2007, 20:12
LocoDelAssembly wrote: That jump would be impossible to encode with rel8/rel16, you have no choice other than rel32 but that is a different problem that the one Tomasz says. Suppose you want to jump from $10000 to $10100, then the calculus would be "$10000 + $100 = $10100", BUT since we are not using the adress size override this will happens: "($10000 + $100) AND $FFFF = $100". $100 obviously is not the expected target so here is of mandatory use the address size override. well maybe you are right, my modified code however went from bad to worse, so I have reverted to the original code and will use an earlier fasm for the 16 bit code. perhaps I put one dword too many, "jmp dword somelabel" seemed to be malfunctioning for nearby labels, WHY do I need "dword" to do eg: .label: jmp dword .label ? surely as a relative jmp that is a few bytes but the current fasm doesnt allow: org 20000h ... .label: jmp .label I'll try doing the dwords again sometime, I wish there was a run time option at least where the dword's are done automatically just for the case of labels, I am trying it out again, this time error message by error message and trying the binary via the earlier fasm after each file, and making backups if the file functions, Last edited by lazer1 on 26 Mar 2007, 21:28; edited 1 time in total |
|||
26 Mar 2007, 20:12 |
|
LocoDelAssembly 26 Mar 2007, 21:00
Oh yes, never realised that, you have to use
Code: db $66
ret I will do some experiments later because since you say that the supposed to be bug code generated by fasm 1.64 works, then maybe there is no 16 upper bits clearing? |
|||
26 Mar 2007, 21:00 |
|
lazer1 27 Mar 2007, 02:26
after many hours of modifying and then compiling with the earlier
fasm I have found the cause of the malfunction when I modified "call f" to "call dword f", call dword f with f: ... ret has the stack wrong on return. Most of my code resets the stack with ebp so the error doesnt matter. But in one file I have a few functions which dont reset the stack which leads to total misfunction. neither "ret" nor "retf" reset the stack correctly. "retf" totally malfunctions. "ret" is ok provided I restore the stack afterwards from a backup in ebp, any ideas what the problem is? is there a way to return from "call dword f" where I dont need to do "mov esp, ebp" afterwards to restore the stack? |
|||
27 Mar 2007, 02:26 |
|
Tomasz Grysztar 27 Mar 2007, 06:26
LocoDelAssembly: just RETD mnemonic is enough (see manual's section 2.1.6). As for the experiments, I made them too (also in long mode), when I realized there was a mentioned bug - and I recall it is documented by both Intel and AMD manuals.
|
|||
27 Mar 2007, 06:26 |
|
lazer1 27 Mar 2007, 13:08
Tomasz Grysztar wrote: LocoDelAssembly: just RETD mnemonic is enough (see manual's section 2.1.6). As for the experiments, I made them too (also in long mode), when I realized there was a mentioned bug - and I recall it is documented by both Intel and AMD manuals. ok, retd is functioning correctly, I still havent completed converting the code, currently I compile the dword code with the earlier fasm, when all files are converted I will compile via the new fasm one problem I found is that there is no form of "loop label" which both the earlier fasm and the current fasm accept, the earlier fasm doesnt accept "loop dword label" but accepts eg "jmp dword label" and "call dword label", I got around that by replacing "loop label" by sub cx, 1 jnz dword label (I dont use "dec" as this code isnt speed critical, I generally avoid the unusual opcodes of 16 bit. In fact I will probably avoid loop in future as it is too complicated to remember: does it loop if cx goes to 0 or from 0? yes I know the answer is to 0, but I have to look that up which wastes time. ) |
|||
27 Mar 2007, 13:08 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.