-5

I don't know if there's a program that can convert ASM to C. I checked google and I've read that IDA Pro can do it but I don't know how. Anyway, how to convert this section of code written in ASM to C?

Here's the code:

#define CALIBRATIONTIME     .10 ;Number Of Times To Measure Signal During Calibration

;**********************************************************************************************
;Calibrate() - Measures A Period From The Input(GP0) Reference Signal
;            - Updates Osccal Value
;            - Updates E^2 
;**********************************************************************************************
CALIBRATE
    movlw   CALIBRATIONTIME
    movwf   COUNTER     ;Calibration Counter

LOW0
    btfsc   INPUT0      ;Wait To Sample Low Edge #0 (Makes Sure We Are Synchronized First Time Through)
    goto    LOW0        

HIGH1
    btfss   INPUT0      ;Wait To Sample High Edge #1
    goto    HIGH1   
    clrf    TMR0        ;Start Timer  (Timer Will Be Behind By 5us After This Instruction)

LOW1
    btfsc   INPUT0      ;Wait To Sample Low Edge #1
    goto    LOW1

HIGH2
    btfss   INPUT0
    goto    HIGH2
    movf    TMR0,W      ;Stop Timer (Timer Will Be Stopped 3us Late)
    addlw   .2      ;Timer Is Behind By 2us Total From Start To Stop    
    call    CHECKPERIOD ;See If Osccal Needs To Be Adjusted

LOW2
    btfsc   INPUT0      ;Wait To Sample Low Edge #2
    goto    LOW2
    decfsz  COUNTER,F   ;Decrement The Calibration Counter
    goto    HIGH1
    call    UPDATE_EE   ;Update E^2
    return
Cœur
  • 37,241
  • 25
  • 195
  • 267
elvinguitar
  • 149
  • 3
  • 6
  • 15
  • You *do* have the algorithm already written out in the comments, it shouldn't be to hard to implement it in another language. – Some programmer dude Oct 01 '15 at 05:16
  • So this would be an "if" statements right? – elvinguitar Oct 01 '15 at 05:27
  • This looks like PIC assembly. – Paul R Oct 01 '15 at 05:57
  • it's called [reverse engineering](https://en.wikipedia.org/wiki/Reverse_engineering) – phuclv Oct 01 '15 at 06:00
  • I'm voting to close this question as off-topic because it belongs to http://reverseengineering.stackexchange.com/ – phuclv Oct 01 '15 at 06:13
  • @LưuVĩnhPhúc This question is about converting well commented source code--it is _not_ reverse engineering. I do this all the time during my work as a kernel/driver programmer. You and others may have been too quick on this. I almost posted the _entire_ conversion to C. It would have taken me about five minutes to code, but I was asking some clarifying questions first [pls see my answer] that were too large for a comment. If I had gotten the answers, I would have replaced my answer with just the converted source. Simple, easy, and not at all vague. – Craig Estey Oct 01 '15 at 08:25
  • @CraigEstey yes indeed I may be too fast. With those comments it's much easier than reverse engineering right from the start. However recommendation for tools is also off-topic here. And the OP should show at least what he tried – phuclv Oct 02 '15 at 02:59
  • It should be closed because the OP needs to specify what part of the conversion they are having problems with, that's the main issue here. "Too broad" is the correct close reason, SO is not a code-writing service. – Lundin Oct 02 '15 at 06:31

1 Answers1

7

This appears to be for a PIC18F microcontroller. Yes? See http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/

The PIC is very old and might have trouble supporting C. Are you trying to rewrite in C for the PIC or to convert to another architecture? Does PIC have a credible C compiler and tool chain?

For basic asm, the symbols on the left are "labels", just like in C.

The PIC has a number of instructions that are "test condition and skip next instruction if true".

For example, the first loop that has the label "LOW0". In C, this would look like:

LOW0:
    if (INPUT0 != 0)
       goto LOW0;

Cleaning this up:

while (INPUT0 != 0);

But, there are a number of undefined symbols: INPUT0, TMR0, COUNTER. The INPUT0 appears to be a memory mapped I/O port, as does TMR0. COUNTER looks like an ordinary global, but you've got to figure out which is which.

There are some calls to other subroutines that aren't defined. Are they in assembly or are they C? If assembly, is the calling convention for arguments the same?

If everything else has already been ported to C, and this is just a straggler, recoding it is trivial. If I had more of those above questions answered, I could have recoded the whole thing in less time than it took me to write this post.

If your project is moving off the PIC arch, it makes sense. What's the motivation [and context]?

UPDATE:

I've downloaded your full file and analyzed it. Caveat: Although I've been doing C for 30+ years and assembler for 40+, I'm a PIC18F newbie, but I've been able to draw on the experience.

The PIC is an 8 bit microcontroller with a single general purpose register called "W" or "working register". It also has "register files", denoted by "F". It has a few instructions that can move bytes to/from W and a given register in a given register file. More on this later.

Print [repeating: Print] all the files/web pages in question. Create a book.

The PIC is relatively simple, with a relatively few instructions. I'd recommend doing your analysis in assembler. By the time you learn enough about the asm and the arch to actually translate into C, you'll actually be able to grok the asm.

The analogy for C is that you're only allowed to do:

if (x) goto label
if (! x) goto label
foo() // with _no_ arguments
W = ...
F[idx] = W
W = F[idx]

First, p12f675.inc is the master definition file for the PIC. It's just a bunch of definitions. Note that ";" is the comment character and is equivalent to C's ANSI "//" [they're both "full line"]. The "EQU" is like a C enum. If you wanted to convert the entire file to a C .h file, change all ";" into "//". Put "enum {" at the top and "};" at the bottom. Then change all:

OSCCAL EQU H'0090'

into:

OSCCAL = 0x0090,

You needn't actually do that, and I recommend against it. Just bite the bullet and get comfy with the EQU syntax.

Here's a general resource: http://www.pic18f.com/ and this tutorial will be pretty helpful getting started: http://www.pic18f.com/tutorial/2007/12/04/18f4550-and-assembly-overview/

For every asm/machine instruction, using the original site I mentioned, print off the given page for the given instruction. For example, for the "movwf", print this page: http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/MOVWF.html

There really aren't that many. And some aren't in the index page. Just google them. In fact, it might just be easier to print every link on the index page. Then, you'd have the complete "instruction set reference"

PIC register files are "banked". The closest analogy I can think of is consider a 2-dim C array: "F[2][256]". But, you can't access F[y][x] directly. You must do a "selectY(1)" [selects "bank" 1] and the a "getF(x)" [gets the x'th register in the given bank]. See the .inc file for values of x for a given bank. Not all values of x may be valid for a given bank. Dunno.

Some of the registers in the register file are I/O ports (e.g. GPIO). Some are internal, such as STATUS. So, after you've transferred the given F register (e.g. STATUS) into the W register, you can then examine individual bits. In the .inc file, there are EQU's (called "equates") for "C" [the processor "carry" flag] and "Z" [the CPU's "zero" flag"].

Note that ".whatever" denotes a constant value (vs a memory location).

Note that the next to last thing the INIT section of your code does is BANKSEL GPIO. So, when we get to executing the LOW0 loop, INPUT0 is replaced by "GPIO,0" which means bit 0 of register GPIO, which is register 5 in bank 0.

In C, access to hardware registers must be marked "volatile", so, for illustration, F should be "volatile unsigned char F[2][256]".

So, to recode "LOW0" again:

LOW0:
    if ((F[0][0x0005] & (1 << 0)) != 0)
        goto LOW0

Also, your main.asm has excellent comments. Try ignoring the asm insts and just read the comments over a few times. Then go back and read over the instruction definitions a few times. Cross reference them.

Oh, yeah. Drawing out the register files on graph paper might help.

The pen is mightier than the sword. And to understand asm, pen and paper can be mightier than the computer :-)

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • 1
    Thank you very much for answering my question and for sharing the link about the instructions in assembly. The code that I posted is just a section of the code. I'm trying to understand the concept of a project by reading the code but I can't fully understand it because the code is written in assembly. Since I do have an average knowledge on C, I'm trying to rewrite the code in C so I can fully understand it. – elvinguitar Oct 02 '15 at 01:44
  • 1
    By the way, the whole code is here: https://www.dropbox.com/s/936xnw75xzfjnfx/main.asm?dl=0 – elvinguitar Oct 02 '15 at 01:51
  • 1
    @elvinguitar Downloaded your file and the .inc and updated my answer with more precise methodology. It's based on how I would do it. – Craig Estey Oct 02 '15 at 07:09