PDA

View Full Version : Only short (signed 8-bit) jumps in assembler?



Johannes
13-11-2010, 01:42
Hello all, let me begin by saying how utterly amazed I am by thinBasic.

Any private programming I did until recently was done on my Acorn RiscPC. That has a very extended BASIC interpreter which has a built-in assembler. And then I needed to bulk-convert half a gigabyte (oh yes) of graphics on my Windows machine.

I looked around and ended up with thinBasic. I wrote several programs in pure BASIC and was already amazed at the execution speed, but converting half a gigabyte of graphics data was impossible in pure BASIC. So I ventured into the assembler. Now, I have been programming assembler for some 25 years, starting on the trusty C64 in 6502 assembler, and the last 20 years were ARM RISC. Programming x86 is... different. ;)

Got that conversion routine working but I will deny having anything to with that code. It's that bad.

A week ago I started on arbitrary-precision math routines and got that working on the ARM. Today I wrote the same routines in x86 assembler and I think I made better use of the x86 instruction set. But I ran into one little problem I can't seem to solve.

At the start of the main routine I perform several jumps based on an incoming parameter. But the assembler will only code short jumps, signed 8-bit displacement, and not 16-bit or 32-bit jumps. Do I need to use other mnemonics or is this impossible with the O2 assembler?

I fixed it by doing a JNE over a CALL to the routine I want. (JMP won't work either because that is also coded as a short jump.)

cmp eax,5
jne not5
call asm_div
ret
.not5

I also noticed that you can enter mnemonics in capitals except for the conditional jumps. Is that intentional or a (very small) bug?

Charles Pegge
13-11-2010, 11:21
Hi Johannes,

I used to do ARM Assembler on the Archimedes back in the 80s, and I look forward to the next opportunity :)

I don't know which version of thinBasic you have but if you use the beta version this will have a very recent Oxygen. Conditional jumps were short by default in the past but now I make them all long as it makes no difference to the performance.

To control the jump operand size explicitly:

jmp short foo 'always 1 byte
jmp long foo 'always 4 bytes
jmp fwd foo 'always 4 byte forward jump



'----------------------------------
'TEST
'==================================

Uses "oxygen"

Dim src As String

src="
asm
###
mov eax,4
cmp eax,5
jne long not5
mbox "is 5"
ret
.NOT5
mbox "is not 5"
ret
###
"

MsgBox 0,O2_view src ': Stop
O2_ASMO src
If Len(O2_ERROR) Then
MsgBox 0, O2_ERROR
Else
O2_EXEC
End If

'msgbox 0,v



Thanks for pointing out the case sensitivity of the conditional jumps. I will fix this today.

One feature you may find useful:

Oxygen labels do not have to be unique. Therefore you can use a standard set of labels many times over. The linker will always use the nearest matching label. The linker searches backwards first. If this is unsuccessful then it logs a forward reference. If you use the jmp fwd option, the linker will not search backwards for the target label.

Charles

Johannes
13-11-2010, 16:30
Charles,

Thank you for the quick reply. So it's that simple? :D

I started programming in assembler on the C64 in R6502/6510 and there all branches (conditional relative jumps) were 8-bit, 16-bit jumps (absolute) were always unconditional. When I switched to ARM all jumps were relative but could handle the entire address space. After twenty years of not caring how far I was branching it was quite a shock to me to see the message come up.

I'm working with version 1.8.0.0 right now. I'll get the beta version and extract the oxygen dll. Again, thanks for the quick solution.