Help with translating this assembly into c
-
21-09-2019 - |
Question
My compiler won't work with an assembly file I have and my other compiler that will won't work with the c files I have. I don't understand assembly. I need to move this over but I'm not getting anywhere fast. Is there someone out there that can help? I can't believe there isn't a translator available. Here is the beginning of the file:
list p=18F4480
#include <p18F4480.inc>
#define _Z STATUS,2
#define _C STATUS,0
GLOBAL AARGB0,AARGB1,AARGB2,AARGB3
GLOBAL BARGB0,BARGB1,BARGB2,BARGB3
GLOBAL ZARGB0,ZARGB1,ZARGB2
GLOBAL REMB0,REMB1
GLOBAL TEMP,TEMPB0,TEMPB1,TEMPB2,TEMPB3
GLOBAL LOOPCOUNT,AEXP,CARGB2
LSB equ 0
MSB equ 7
math_data UDATA
AARGB0 RES 1
AARGB1 RES 1
AARGB2 RES 1
AARGB3 RES 1
BARGB0 RES 1
BARGB1 RES 1
BARGB2 RES 1
BARGB3 RES 1
REMB0 RES 1
REMB1 RES 1
REMB2 RES 1
REMB3 RES 1
TEMP RES 1
TEMPB0 RES 1
TEMPB1 RES 1
TEMPB2 RES 1
TEMPB3 RES 1
ZARGB0 RES 1
ZARGB1 RES 1
ZARGB2 RES 1
CARGB2 RES 1
AEXP RES 1
LOOPCOUNT RES 1
math_code CODE
;---------------------------------------------------------------------
; 24-BIT ADDITION
_24_BitAdd
GLOBAL _24_BitAdd
movf BARGB2,w
addwf AARGB2,f
movf BARGB1,w
btfsc _C
incfsz BARGB1,w
addwf AARGB1,f
movf BARGB0,w
btfsc _C
incfsz BARGB0,w
addwf AARGB0,f
return
I get that I can largly exclude the first two lines as the device defines are in my main.c anyway. The two #defines are just that, but the simplest way (I think) is to just replace instances of _Z and _C with STATUS,2 and STATUS,0 accordingly. The next lines (the GLOBALs) are simply variable declarations I'm gathering. Same with LSB and MSB except they also assign values. The next chunck I think I just declare a bunch of integers with those names (AARGB0, etc) and then the chunck after that is a function.
I don't even bother to translate that function, because my compiler has #asm/#end asm directives so I can put it in raw (as long as its wrapped in a function).
I think I have it all... until I build and my compiler screams about STATUS not being defined. And of course its not. But what is it? I read on the net that STATUS registers are something special but I really don't get how it works.
If you haven't noticed, I'm not even sure what it is I'm really asking. I just want the bloody thing to work.
Solution
STATUS is a built-in register in the PIC architecture, that implements the same functionality as the "status" or "condition" flags register in most larger CPU:s. It contains bitflags that are set and cleared by the microcontroller as it executes code, telling you the result of operations.
The Z flag, for instance, is set whenever an arithmetic operation results in a zero, and the C (carry) flag is set when arithmetic overflow is detected.
These are flags that are typically not visible from C, as C doesn't want to require that the host processor even has status bits, so directly translating this code to C will be hard. You will need to figure out a way to include the status-reading bit tests in the C code, and use those instructions when possible. This might be troublesome, as from C you have less control over which registers are being used, which in turn might make it hard to make sure you're checking the proper flags in the right place(s).
Here are a few links to other people's extended precision PIC code. Most seem to remain in assembly, but they might still be useful as references or inspiration.
OTHER TIPS
Your compilers are refusing your source?
Either you are using broken tools, or your source files are buggy. In both cases, your problem is not "translating ASM to C" or something like that, but the bugs in your source / toolchain. Do not try to work around problems, solve them.
You can try to reverse-engineer the disassembly. But what will you learn?
You should be able to compile your assembly (using compiler 1) into an object file, and link that to the object file compiled by compiler 2 from your C file.