-
Illogicalities of 68xx assembly
Posted by
metertech58761
on 21 Apr, 2023 14:02
-
So I'm trying to untangle this plate of spaghetti that passes for 6801 assembly, and have come across a bit of a headscratcher. I want to see if anyone else can make sense of it:
LDAB #$0C
LDAA #$00
BNE LB_F884
ORAB #$30
LB_F884 ORAB NVR_39
STAB NVR_39
LDAA #$06
LDAB #$01
BEQ LB_F8A0
ASLA
LB_F8A0 STAA NVR_1E
If I'm right, I should be able to replace them with equivalent code:
LDAB NVR_39
ORAB #$3C
STAB NVR_39
LDAA #$0C
STAA NVR_1E
Right?
Looking a bit further down I see this little gem:
LDAA #$00
BEQ ...
Here, I should be able to just cut everything out between this and the target, right?
-
#1 Reply
Posted by
wofritz
on 21 Apr, 2023 14:34
-
Looking a bit further down I see this little gem:
I don't know about the 68xx, but on the Z80 loading something into accumulator does not modify the flags
-
#2 Reply
Posted by
bingo600
on 21 Apr, 2023 14:58
-
Looking a bit further down I see this little gem:
I don't know about the 68xx, but on the Z80 loading something into accumulator does not modify the flags
The 68xx register loads will affect ie. the Z Flag
-
-
bingo600: Right, so clearing the accumulator by loading a 0, followed by a BEQ means everything from that point to the target is completely ignored, correct? There are no 'external' calls into that block either.
-
#4 Reply
Posted by
bingo600
on 21 Apr, 2023 15:14
-
bingo600: Right, so clearing the accumulator by loading a 0, followed by a BEQ means everything from that point to the target is completely ignored, correct? There are no 'external' calls into that block either.
That would seem to be correct , LDAA #$00 would set the Z Flag , and the BEQ would always be true
As i see it further up , it'll always ORAB #$30 , and never ASLA
Hope some compiler did that code, not a person.
/Bingo
-
#5 Reply
Posted by
RoGeorge
on 21 Apr, 2023 15:55
-
I don't know 6800 assembly, but when disassembled code seems illogical, check you are not decoding data. Back then data and code were often mixed in the same memory, no separation.
Second, could be a timing loop, where the programmer counted the instructions and their execution time. It was a known technique to insert some useless instruction only to match the desired machine cycles you wanted the delay to be.
Third, encrypted firmware and/or hardware protection against copying was not yet a thing, but reverse engineering was a thing. Therefore, once in a while you may see intentionally irrational code, meant to make it harder to understand so to obfuscate the algorithm intended to protect.
-
-
Hope some compiler did that code, not a person.
I would hope so as well!
Actually, the first part of my code was two separate sections, so I went back and tweaked the post for clarity.
I haven't come back to that part of the code, but I have seen where it OR'd a number with 00...
I wonder if it's some kind of template code where certain values are changed in the binary before burning to EPROM? (different options installed etc.) I'll probably have to start making notations in the 'reference' copy of the source that I made.
-
-
RoGeorge: re: data and code mixed in the same section, I have run into that in the past, and thankfully is not the case with this particular block (I did identify two sections elsewhere where a table was adjacent to the code using it).
Timing.... the main clock is only 1MHz - I don't think cycle counting would be a factor with such a low speed?
Obfuscation.... that could well be part of what I'm running into.
Also, this code when fully expanded (all reused code duplicated as needed to reduce the number of JMP and BRA) appears to be about 5.5 kilobytes, squeezed down to fit on a 4K EPROM with < 100 bytes to spare.
-
#8 Reply
Posted by
RoGeorge
on 21 Apr, 2023 16:17
-
Timing.... the main clock is only 1MHz - I don't think cycle counting would be a factor with such a low speed?
Not saying the particular code you posted is a timing loop, but in general, the smaller the clock the more attention it needs.
For example when generating musical tones, one might need to carefully count how many machine cycles are in the loop, so the musical note is close enough, so it won't sound fake. Nowadays hardware timers and PWM peripherals are common to any microcontroller, but that wasn't the case back then. So, the programmers had to carefully count the clocks needed to execute each instruction, so to generate in software the needed musical note, or the needed PWM ratio.
-
-
OK, so another bit of confusing code:
LB_F4E6 ANDB #$0F
CMPB #$04
BPL LB_F51B
INCA
SEC
ORAB #$00 ; ???
BEQ LB_F4F6 ; ???
LB_F4F2 ROLA
DECB
BNE LB_F4F2
LB_F4F6 STAA DCT_97
JMP LB_F48F
Why would I want to OR something with 0?
-
#10 Reply
Posted by
RoGeorge
on 26 Apr, 2023 11:02
-
Sometimes an operation that doesn't change any number is done only to set the flags.
For example, check if the number is zero by OR-ing it with zero (will let the number unchanged), then looking at the zero flag. Again, I don't know 6800 assembly, only telling generic tricks. Don't know if that applies to the code you see.
-
#11 Reply
Posted by
DiTBho
on 26 Apr, 2023 11:43
-
on MIPS you test-and-branch with a single instruction
on 68HC11 and 68000 first you test, then you branch
test means: operation (register) --> change some flag in a dedicated register
branch means: check a specific flag/s in the dedicated register, and if they match your condition (is it zero? is it not_zero? is it carry? is it overflow? is it underflow? is it GE? is it LE? GT? LT? EQ? NEQ?, than branch, otherwise do nothing and execute the next instruction
MIPS needs routines to check { carry, overflow, underflow }
-
-
If I wanted to check for the Z flag, it would make more sense to start with TSTB or a CMPB #$00 instead of ORA #$00...?
The load management terminal actually had a number of different options (up to three Form A and up to three Form C contact inputs, up to four relay outputs, one of which could be a latched type, two rate annunciator outputs), and if the ADC daughterboard and its EPROM were present, up to four transducers could be handled.
I'm starting to wonder if these 'illogicalities' I'm seeing are actually 'software switches' that are turned on / off to configure the various options.
-
#13 Reply
Posted by
WattsThat
on 26 Apr, 2023 12:35
-
Limited experience in 6800 but in the 8008/8080/Z80 world:
Adding a forth possibility to RoGeorges post #5, is when hand crafted, non compiler generated code involves a branch that makes no sense - you have possible target for dynamic code modification. Changing the branch type or target address of the branch was a common code space compaction technique when ram was expensive and limited.
You’ll see other indications of said dubious techniques, a RET followed by two NOP’s was a common way to extend a subroutine by dynamically replacing the three byte sequence with a jump to continue execution elsewhere.
-
#14 Reply
Posted by
Kleinstein
on 26 Apr, 2023 12:41
-
I don't know the 6800, but there is a chance that TSTB is just a short cut for an ORAB #00 and just the dissassember does not use it. There are sometimes alternative names to make code a little more readabel.
-
#15 Reply
Posted by
5U4GB
on 29 Apr, 2023 10:30
-
Second, could be a timing loop, where the programmer counted the instructions and their execution time. It was a known technique to insert some useless instruction only to match the desired machine cycles you wanted the delay to be.
Another thing to look out for is whether there's other code that jumps into the middle of instructions there. You could save space in 8-bit code by eliminating branches, which could be done by laying things out so you could jump into the middle of another instruction so that depending on which way you came in one or the other instructions turned into no-op equivalents. This was fairly standard in handcoded assembly when you knew all the opcodes.
-
-
5U4: I remember that trick back in the day... on the 6502-class MPUs, the BIT opcode was especially handy for this.
But this firmware I'm picking away at makes HEAVY use of BRA to reuse code... it's how they managed to squeeze 5.5K into just under 4K...
-
-
Think I finally found some obfuscation code -
LB_FD52 BSR LB_FD57
JMP LB_FEFF
LB_FD57 LDAA NVR_1A
CMPA #$01
BEQ LB_FD5F
RTS
LB_FD5F LDAB SRM_C6
and which, if I juggle a couple lines, looks like it should be:
LB_FD52 LDAA NVR_1A
CMPA #$01
BEQ LB_FD5F
JMP LB_FEFF
LB_FD5F LDAB SRM_C6
right? There is NO other call to the "subroutine" at LB_FD57.