Mis-aligned BASIC assembly
Timothy Baldwin (184) 242 posts |
Consider the following buggy BASIC assembler:
The syscall% label is not aligned, however BBC BASIC V 1.77 (29 Jun 2019) assembles it without error, silently inserting 2 bytes before the push instruction:
Furthermore executing the entire routine with Alas it fails on Cortex-A72 with an exception. It would be helpful if BASIC raise an error when trying to assemble an incorrectly aligned instruction. |
Jeffrey Lee (213) 6048 posts |
Agreed. I can think of one case where adding the error could break existing code (think of situations similar to the CD_Register R1 parameter – data followed by code, if the data part isn’t required to be a word multiple then a programmer who knows BASIC will automatically align code to 4 bytes might not add an explicit ALIGN). But since new CPUs are more strict about things (+ there’s the danger of accidentally dropping into Thumb mode and crashing in a worse way) it’s probably better for BASIC to complain. |
Martin Avison (27) 1494 posts |
Trouble is that a label is not an instruction? In this case it is to be used as an address for a CALL, but other labels may reference some data, say a string, which does not need to be aligned. Could the assembler differentiate which labels need to be aligned? |
Jeff Doggett (257) 234 posts |
It’s not the label that should be aligned – for instance hw2% should not be aligned. |
Rick Murray (539) 13850 posts |
Yes. Older processors (early ARMv7 and stuff prior) used to just ignore wonky addresses by ignoring the bottom two bits. Newer processors fault this, so it’s important to have addresses of code aligned unless there’s a specific directive/option to say otherwise. It’s this issue exactly that caused ZapObey to fail on newer processors. |
Jeff Doggett (257) 234 posts |
I think that the problem will be more subtle than just calling an address that isn’t aligned as the branch intructions have offsets in words (IIRC). So the CPU could execute the instruction before the one intended. |
Timothy Baldwin (184) 242 posts |
Perhaps only complain if the label immediately precedes the misaligned instruction. |
Timothy Baldwin (184) 242 posts |
Perhaps only complain if the label immediately precedes the misaligned instruction. |
Jeffrey Lee (213) 6048 posts |
But then it won’t warn people about a more common problem: SWI "XOS_WriteS" DCB "hi" DCB 0 MOV r0,#123 Edit: Actually that’s nonsense, since the programmer doesn’t need warning in that case. But I can imagine that OS_WriteS is one common situation where a knowledgeable/lazy programmer may have skipped the explicit ALIGN. So yes, your suggestion of having it only throw an error if the instruction is directly following a label would make sense. |
nemo (145) 2554 posts |
The assembler cannot know the intention of the programmer. Does the misaligned label mark the start of the next instruction, or the end of the byte data? More likely to be the former. But not impossible it’s the latter. Any change in behaviour must be explicitly switched on, not imposed on existing code. It’s getting to the point where Basic needs a pragma. |
Martin Avison (27) 1494 posts |
I can see no reason for assembling an executable instruction at a non-aligned address. If executed it would cause problems, whatever the cpu, so could/should raise an error during assembly. Labels however sometimes need to be unaligned. |
Stuart Swales (1481) 351 posts |
Yes, instructions must continue to be padded to be aligned to a word boundary or many progs would break. Anyhow you could warn if a branch instruction was composed with an unaligned_address% target. Ditto CALL unaligned_address%. I realise that’s the tip of the iceberg in the realm of ways of setting the PC to an address in ARM code, but it’s probably helpful for most of them in BASIC. |
nemo (145) 2554 posts |
Martin, the instruction has never been assembled unaligned. It has always auto-aligned. This has never been an error. To suddenly impose errors on unchanged code is the wrong approach. If it is desirable to catch this error (and I stress, the precise nature of the error is not clearly defined) then that should be an option the programmer must switch on. An error must not be imposed on shipped code.
That’ll fail anyway on some cores, as has been pointed out, perhaps a better error report would be useful. ie if the CPU doesn’t support unaligned addresses, then BASIC can whinge about them.
Indeed. But auto-alignment before an instruction is normal, and cannot be considered any kind of error. |