[fpc-pascal] Branch table

Marco Borsari borsa77 at libero.it
Fri Aug 17 15:46:17 CEST 2018


Il 16/08/2018 17:40, Giuliano Colla ha scritto:

> The first thing I notice is that you load BX, which is a 16 bit register
> (the lower 16 bits of EBX), with the value of "next", and then Jump to
> the content of EBX which is a 32 bit register, whose lower 16 bits have
> been loaded but whose upper 16 bits are undefined. A SIGSEV is therefore
> to be expected. If you are in a 32 Bit environment you should use EBX,
> if you're in a 64 Bit environment you should use RBX.

Thank you, I have made the correction you suggested, but I obtain a 
segmentation fault again. Indeed new code is

program branch;
{$ASMMODE intel}
label next,stop,a,b,c;
var idx:byte;
begin
write('Index? ');
readln(idx);
asm
mov al,idx;
shl ax,2;
mov ebx,next;
add ebx,eax;
jmp ebx;
next:
jmp a;
jmp b;
jmp c;
end['EAX','EBX'];
a:
writeln('0');
goto stop;
b:
writeln('1');
goto stop;
c:
writeln('2');
stop:
writeln('stop');
end.

Also for what I understand jmp does not require to refer to the address 
in the register.

> What I would do, if I were in your place, would be to rewrite your
> program in pure Pascal, compile it with the -a switch to get the
> assembler listing, and use the compiler generated assembler code as a
> guideline to your optimized assembler.

I found that someone made that for me at link
http://www.mindfruit.co.uk/2012/01/switch-blocks-jump-tables.html
and I have tried to rewrite the program in at&t syntax

program branch2;
{$ASMMODE att}
label next,stop,a,b,c;
var idx:byte;
begin
write('Index? ');
readln(idx);
asm
movb idx,%al
jmp *next(,%eax,4)
next:
jmp a;
jmp b;
jmp c;
end['EAX'];
a:
writeln('0');
goto stop;
b:
writeln('1');
goto stop;
c:
writeln('2');
stop:
writeln('stop');
end.

but this fails compilation at line 10 with messages
Unsupported symbol type for operand
Unknown identifier 'NEXT'
Well, I think I can live without it, it is only for
the sake of curiosity,
Marco



More information about the fpc-pascal mailing list