How to solve the "Fixup Error" - Error 515

Started by Theo Gottwald, June 05, 2010, 08:07:55 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

How to solve the "Fixup Error" - Error 515

Jeff from the PB-Support writes:

QuoteA jecxz will always be a short jump. And if you have short jumps and then add the trace statements, code will be inserted into your application and your jump to locations may not be in the short range anymore and will cause Fixup errors. You can convert your jecxz to test ecx, ecx and jz and not use a short jump, this will allow your program to run with the trace option.

QuoteYou simply need to check your jump shorts to make sure that they do not exceed the maximum length or use a jump instruction. You must remember that extra bytes will be added to your code with #debug code on, which is necessary to check for an error after each line.

But its not that easy in big projects, as the Compiler (PB 9 or earlier) does something unexpected, he doesn't do in any other case.
The PB 9 Compiler does not display the Line number where the error occured, nor even tell in which file!

Even the help file does not help so much as needed.
Imagine a big ASM Project, you have to guess where the JMP Instruction was jumping "too short".

You can find it by leaving out - Step-by-Step- one Module after the next.

After i found the ASM Subprogramm that did the mistake, i tried to use the new Compiler-Instruction #DEBUG CODE OFF.
I thought "This will turn the debug code generation off and leave my ASM Code untouched".

And realized that it did not help at all. And the sollution?


This will turn off the code generation that brings up the Fixup-Error.
In the same way watch for TRACE ON  statements, as they will have also this effect.

At  least there may be help in the future somewhere. 15.06.2009, 18:34 I got this mail:

QuoteHi Theo,

I have logged this with R&D. Thank you.

Jeff Daniels
PowerBASIC Staff

Better in PB 10!
In PB 10 things are much easier (often not always)!
PB 10 displays often exactly the line where to change JMP-code. In the IDE the cursor will jump to the Line you may need to change.

Steve Hutchesson


Take the easy way our, never never use "jecxz" as it is a leftover from the DOS days, do it the fast easy way with non-limited jump range.

    test ecx, ecx
    jz label

This code is always faster although you may not notice it in some places.

Theo Gottwald

Good to know, Steve.

Quotetest ecx, ecx
   jz label

I thought before, the short Jumps would be faster.

Steve Hutchesson

Funny enough Theo, years ago I bothered to code some MASM test pieces testing the difference between short range instructions and the later longer ones and the later ones were generally faster. The very minor size gain of using the shorter instructions did not add up to any advantage at all. It appears to be the case that the longer instructions (opcode wise) are scheduled easier through the processor pipelines than the shorter ones.

What you avoid if possible is complex instructions and the JECXZ family of instructions not only do a test for zero but perform the conditional branching as well and this tends to make them slow as the processor under the hood is closer to RISC than CISC. The Core2 quad I mainly use is closer to a PIII that a PIV in preferred instructions and the recent i7 I have built is another animal again.

Theo Gottwald

QuoteIt appears to be the case that the longer instructions (opcode wise) are scheduled easier through the processor pipelines than the shorter ones.

That will really make me change some code. I thought the fact that the CPU has to catch less bytes would be an advantage, nut it may even be an disadvantage in terms of Alignment/Pipelinign as you said.

Good to know.

@Hutch, do you also make an MASMx64 / use ASM for x64 Hutch?
I've just read something on that from Patrice.

To me i'd say its not much different, just more registers.
Can you comment on x64 ASM?

Steve Hutchesson


I am not personally rushing into Win 64 as it is not without its problems. On the up side it has twice the registers and at the mnemonic level it is fast but on the down side it uses far more memory and uses a far more complicAted stack and SEH technique for system API calls so unless you need linear addressing greater than 2 gig it has no advantage.

Full 64 bit games/graphics application appear to work better in that they can feed video data to the graphics cards faster. Big databases and similar applications win out with the linear addressing range and the CAD guys can use that extra capacity but for the vast majority of user and technical applications 64 bit is just not developed well enough yet.

When the hardware is a lot larger, cores are faster and with more available 64 bit will come into its own for wide ranging user applications but that time is not here yet.

Theo Gottwald


Two questions ... how would you implement it ...

1. How many REGISTER Variables do you expect can we use in a future PowerBasic x64? (Actually we have 2 in PB/Win32).

2. Will LONG's be 64 bit wide and which lenght do you think would QUADS have in PB x64?
   Or wil LONGS stay 32 bit and QUADS what they are and we get then a new Datatype "DQUAD" und SDQuad" (Signed DQuad) ?

Steve Hutchesson


Most of you first question is answered by the Intel ABI (Application Binary Interface) and I have no doubt that in a future Win64 version of PB that it will properly comply with this spec as Windows 64 does.

The following question is one you would have to point at Bob but I personally favour being able to distinguish the BYTE size of a variable by its name and not keep reusing earlier ones as later larger sizes.

In MASM you have BYTE (8 bit) WORD (16 bit) DWORD (32 bit) QWORD (64 bit) and OWORD (128 bit) as well as the REAL4 REAL8 and REAL10 for 32, 64 and 80 bit floating point maths and these are all native hardware defined data sizes and I would prefer to see PB follow these as it does in its 32 bit compilers.

Long ago a WORD was related to the native data size of the processor and has over time meant that it was 8, 16 and 32 bit which is confusing when a programmer has to match a data size to a data name.

Mike Stefanik

Quote from: Theo Gottwald on June 08, 2010, 07:00:21 AM
Will LONG's be 64 bit wide and which lenght do you think would QUADS have in PB x64?
Or wil LONGS stay 32 bit and QUADS what they are and we get then a new Datatype "DQUAD" und SDQuad" (Signed DQuad) ?

Windows x64 uses the LLP64 data model, which means that only pointer sizes change and all other intrinsic data types remain the same. LONG, DWORD, INTEGER and so on stay the same 32-bit values. PowerBasic already has the QWORD type (64-bit integer). However, in terms of the Windows API, there are some important differences in how certain common API types are defined.

The thing that you have to be really mindful of is dealing with anything that uses pointers or pointer manipulation (obviously), handles and callback parameters. As a simple example, consider the EnumFonts function, which looks like:

int EnumFonts(
    HDC hdc,
    LPCTSTR lpFaceName,
    FONTENUMPROC lpFontFunc,
    LPARAM lParam

That last user-defined callback parameter is declared as LPARAM, and if you're used to programming in 32-bit Windows you're going to think of that as a long, a 32-bit integer; you might even pass in a pointer to something that your callback function will use. Execept that on an x64 system, LPARAM is actually defined as LONG_PTR.

If you look at current Windows API documentation, you'll often see things like DWORD_PTR, LONG_PTR, UINT_PTR and so on. What those values mean is that they're integers (signed or unsigned, depending) but large enough to store whatever the intrinsic pointer size is. So, LPARAM on a 32-bit system is 32-bits, but on a 64-bit system it's 64-bits. A lot of programmers can get bitten by this because they're so used to to thinking that LPARAM = LONG, which is not the case on x64 systems. So wherever you see API functions that use or return LPARAM, WPARAM, LRESULT, SIZE_T, HANDLE or most other HXXXXX types, then you need to be careful (and then there's the exceptions... like the fact that HRESULT is always just 32-bits, regardless of platform).