Illogicalities of 68xx assembly - Page 1
Forum section: electronics / general

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 21, 2023, 02:02:03 pm
content: 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:Code:LDAB #$0CLDAA #$00BNE LB_F884ORAB #$30LB_F884ORAB NVR_39STAB NVR_39Code:LDAA #$06LDAB #$01BEQ LB_F8A0ASLALB_F8A0STAA NVR_1EIf I'm right, I should be able to replace them with equivalent code:Code:LDAB NVR_39ORAB #$3CSTAB NVR_39Code:LDAA #$0CSTAA NVR_1ERight?Looking a bit further down I see this little gem:Code:LDAA #$00BEQ ...Here, I should be able to just cut everything out between this and the target, right?

author: wofritz
author_rank: Contributor
timestamp: April 21, 2023, 02:34:37 pm
content: QuoteI don't know about the 68xx, but on the Z80 loading something into accumulator does not modify the flags

author: bingo600
author_rank: Super Contributor
timestamp: April 21, 2023, 02:58:27 pm
content: Quote from: wofritz on April 21, 2023, 02:34:37 pmThe 68xx register loads will affect ie. the Z Flag

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 21, 2023, 03:07:00 pm
content: 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.

author: bingo600
author_rank: Super Contributor
timestamp: April 21, 2023, 03:14:25 pm
content: Quote from: metertech58761 on April 21, 2023, 03:07:00 pmThat would seem to be correct , LDAA #$00 would set the Z Flag , and the BEQ would always be trueAs i see it further up , it'll always ORAB #$30 , and never ASLAHope some compiler did that code, not a person./Bingo

author: RoGeorge
author_rank: Super Contributor
timestamp: April 21, 2023, 03:55:20 pm
content: 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.

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 21, 2023, 03:58:52 pm
content: Quote from: bingo600 on April 21, 2023, 03:14:25 pmI 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.

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 21, 2023, 04:06:08 pm
content: 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.

author: RoGeorge
author_rank: Super Contributor
timestamp: April 21, 2023, 04:17:17 pm
content: Quote from: metertech58761 on April 21, 2023, 04:06:08 pmNot 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.

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 26, 2023, 09:14:43 am
content: OK, so another bit of confusing code:Code:LB_F4E6ANDB #$0FCMPB #$04BPL LB_F51BINCASECORAB #$00 ; ???BEQ LB_F4F6 ; ???LB_F4F2ROLADECBBNE LB_F4F2LB_F4F6STAA DCT_97JMP LB_F48FWhy would I want to OR something with 0?

author: RoGeorge
author_rank: Super Contributor
timestamp: April 26, 2023, 11:02:17 am
content: 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.

author: DiTBho
author_rank: Super Contributor
timestamp: April 26, 2023, 11:43:32 am
content: on MIPS you test-and-branch with a single instructionon 68HC11 and 68000 first you test, then you branchtest means: operation (register) --> change some flag in a dedicated registerbranch 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 instructionMIPS needs routines to check { carry, overflow, underflow }

author: metertech58761
author_rank: Frequent Contributor
timestamp: April 26, 2023, 12:16:18 pm
content: 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.

author: WattsThat
author_rank: Frequent Contributor
timestamp: April 26, 2023, 12:35:38 pm
content: 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.

author: Kleinstein
author_rank: Super Contributor
timestamp: April 26, 2023, 12:41:49 pm
content: 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.

author: 5U4GB
author_rank: Super Contributor
timestamp: April 29, 2023, 10:30:51 am
content: Quote from: RoGeorge on April 21, 2023, 03:55:20 pmAnother 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.

author: metertech58761
author_rank: Frequent Contributor
timestamp: May 01, 2023, 06:55:22 am
content: 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...

author: metertech58761
author_rank: Frequent Contributor
timestamp: May 01, 2023, 07:05:56 am
content: Think I finally found some obfuscation code -Code:LB_FD52BSR LB_FD57JMP LB_FEFFLB_FD57LDAA NVR_1ACMPA #$01BEQ LB_FD5FRTSLB_FD5FLDAB SRM_C6and which, if I juggle a couple lines, looks like it should be:Code:LB_FD52LDAA NVR_1ACMPA #$01BEQ LB_FD5FJMP LB_FEFFLB_FD5FLDAB SRM_C6right? There is NO other call to the "subroutine" at LB_FD57.