Forum > General

Relocatable relative assembly jump by value instead of label - SOLVED?

(1/2) > >>

Compiler / linker is confused by relative short jumps with an immediate value. Thinks they are a label or something..

dec cl
jnz -15

converting -15 to $f1 hex value doesn't work either. Only manual machine code works, like so:

db $75; db $f1

Assembly coders use relocatable macros using relative negative jumps for relocatable loops. FPC macros don't work in assembly sections, instead an external .inc file has to be written for each macro. It's not ideal but OK.

// rcx = bits count 1..64 .. esi = ink .. bx = jump for way 0  .. dx = jump for way 1 
// r8 = bits indicating forward / diagonal cursor movement for fast circles, arcs, expansions..

{    loop bits      }  // not an actual label, just a comment
{$i   dot            }  // mov [rdi], esi
{$i   goWay0or1 } // mov ax, bx  ;  shr r8, 1  ;  cmovc ax, dx ;  add rdi, eax // if shifted bit=1 : jump bitmap stride+n else jump n
{$i  nextBit        } // dec cl ; db $75; db $f1  // jnz -15 should work as an immediate relative jump by default.
{$i  dot              } // mov [rdi], esi  // last pixel drawn

If anyone knows what I'm doing wrong, if I am, then please explain as I can't find a solution in the forum or documentation.... I've tried adding 'near'... Just finding 'offset' had to be added as a prefix to load immediate global variable addresses into registers was a real chore too..

TASM has "short" label type for this purpose, but FPC doesn't seem to support it.

I.e. you can't do something like this:

--- Code: ---  asm
    mov eax, eax
    jnz short @test

--- End code ---

P.S. Delphi doesn't support "short" label type too, but at least it compiles to right opcodes (see attachment). May be it depends on optimization settings?

Cheers.. I forgot to say I'd tried 'short' as well as 'near' with no luck.. Short is parsed but does nothing, same for 'near'.. Also 'byte', 'smallint', 'shortint' don't work. The compiler is telling the linker it's a synthetic absolute label that needs to be converted into a relative 8 bit jump...
This is a BUG to me... Not just a limitation with hacky work-around... Lack of macro support in assembly blocks almost is too - although the {i <EXTERNAL FILE>} solution can be neatened up, but all those external '.inc' files are a pain.. What gets me with almost all high level languages is they do not do 'the basics' properly... Engineers know macros can weaken data type and language integrity but deal with that, no problem..
Assembly macros should be available in every assembler, and macro relocation should be automatic, but if not, at least parse numeric values in jump statements as relative jumps. I can see it's a compiler-linker problem. I'd fix it if I knew where to look and have the time.
I am not asking for 'inlined assembler procedures', even though many of us want them. I see why this is being avoided - but still no excuse not to implement macros in assembly blocks and relative jumps by numeric value.

For me "short" doesn't even compile.

Hmmm. May be I missed something, when I was doing it for the first time, but now exactly the same example compiles to right opcodes (see attachment).

I'm not sure, how compatible with TASM FPC inline assembler is. I mean, original Delphi's inline assembler should have been very compatible with TASM. And FPC's assembler should mimic it. And in TASM adding @@ to label turns it into local label, i.e. scope-unique label.

If you need to use macros so much, then it would be better for you to use external assembler to compile some routines into separate obj files and then link them to your project.

My experience shows, that FPC optimization is great and using assembler to produce CPU-tick-precise code isn't needed in most cases. ASM syndrome, i.e. assumption, that raw ASM code is always faster, is bad thing. Modern optimized code is as fast, as bare assembler, but you don't need to waste your time on routine things, like caring about register allocation, instead of actually writing your code.

In my experience 'ASM syndrome' is yet another high level excuse for not doing low-level work when it's easy, as in the case I demonstrated. Easy to program whilst guaranteeing equal or better performance than the compiled version. Easy to roll-out similar methods (ie. small lines and arcs rotated 8 or 4 ways).
The FPC 'bitpacked' types produce pretty efficient code, but I can beat it with assembly and it's easier when it comes to nitty-gritty bit manipulation with a bit of practice. Macros reduce procedure calls... These are all tight little loops and tight, rapidly repeated procedures. Inlined code and assembler macros enable higher code engineering standards... and more speed.
This tiny engine could run on a 68000 or even Z80 using 16kb of tiny arc, line, circle and interpolation + a few fast math lookup tables.. It also happens to work well on modern systems.  FPC and Lazarus is a fine effort, and Delphi 7 32bit for compiled Win32 apps was a masterpiece for its time. FPC does a very good job at optimisation with plenty of control - but also lack of it at times...
Yes, I use external assemblers and assembly tools, but I am an into INTEGRATED development environments and assessing many.


[0] Message Index

[#] Next page

Go to full version