# Creating an ASM file that will return the characters located in 8 consecutive registers

I have to create an ASM file for the PIC18F452 that does the following:

(a) define the label MapName as the first of 8 consecutive registers containing a null-terminated string of not more than 7 characters. (b) access an 8-bit unsigned integer variable called MapIndex which was declared in a C file. (c) define an ASM function getMapChar which can be called from C using the function prototype char getMapChar(void). The function should return the appropriate character when the value of MapIndex is <= 7 or the value 255 if MapIndex is > 7. (d) make the labels MapName and getMapChar accessible to an external C file.

My code so far is shown below:

; Configuration word : WDT off, power-up timer on, code protect off, RC oscillator
list = p18f452
MapName         equ             0x20
MapName1        equ             0x21
MapName2        equ             0x22
MapName3        equ             0x23
MapName4        equ             0x24
MapName5        equ             0x25
MapName6        equ             0x26
MapName7        equ             0x27
CurrentChar     equ             0x28

extern      MapIndex
org             0x00
goto            getMapChar

getMapChar                  movlw           0x00
movwf           MapName7

GLOBAL      getMapChar
GLOBAL      MapName

END


I have already done parts (a), (b) and (d) but I am having some problems with writing the code that moves through each of the consecutive registers automatically using the value of MapIndex. Could anyone help me please? It would be much appreciated.

• what is the issue you are having with this code specifically? Parsing the strings? Indexing the registers? – Kortuk Sep 30 '11 at 12:57
• @Kortuk - Indexing the registers – D Brown Sep 30 '11 at 13:05
• Why must this be done in ASM? There won't be much of a performance boost to doing it in C and just accessing elements in a char array. – Majenko Sep 30 '11 at 13:27
• @Majenko - I was thinking the same thing, but it's an assignment that I have to do – D Brown Sep 30 '11 at 13:34
• @Majenko: Clearly the point here is learning, not getting a particular project done. All EEs should be required to do a few projects in assembler as part of their training so that they understand how machines really function at the low level, what a compiler really does, what calling conventions are, etc. It seems this is exactly what the OP is having problems with. Unfortunately, he is still missing so much background knowledge that this is not a chunk he can chew on yet. For starters he should do a very simple pure asm project to understand the basics before adding a compiler to the mix. – Olin Lathrop Oct 1 '11 at 13:51

Step back and think about the whole problem. No, you haven't done A, B, and D yet. There are so many things wrong here that demonstrate such major misunderstanding that I don't know how to begin explaining. All I can do is enumerate some problems:

1. You haven't defined any variables at all. All EQU does is create a symbol of a particular value. It has nothing to do with allocating variables. Only the RES directive does that.

2. You seem to be writing this in absolute mode. You didn't say what compiler you are using, but most likely it only works in relocatable mode.

3. You don't need a label for every byte in the buffer. The MapNamex names are clutter that gives the impression these names will be used separately. In reality, you'll never use them because you will be indexing into the buffer at run time.

4. This code is written like it's the single stand-alone module of a project. Clearly this can't be if there is at least one C routine in the project.

5. The C runtime library needs to be initialized at startup, but you are preventing that by trying to own the reset vector.

6. You are running your routine directly from the reset vector. That makes no sense since it is intended to be called from C. You need to create a subroutine.

7. There is no place for the code to go two instructions after getMapChar. Your code just ends, so the machine will execute whatever happens to be in memory after the last instruction in this module. That makes no sense.

You need to step back and try to understand how compiled code gets run on the machine, what the subroutine linkage conventions are, and then how to implement them in assembler to make a C function that returns a byte. Try to understand the role of compiler, assembler, and linker and how they interact. You're nowhere near ready for this problem yet.

• Thanks for the tough love there Olin. It's been a while since I've had to do programming for embedded systems, and there's obviously a lot that I have forgotten or didn't learn properly in the first place. So thanks for the brutal honesty, it was a real eye-opener :-) – D Brown Oct 1 '11 at 23:42
• And to answer the question in #2, I'm using the C18 compiler for this one. – D Brown Oct 1 '11 at 23:56
• @DBrown: I'm pretty sure C18 requires relocatable mode. I'm also reasonably sure that a C18 function that returns a single byte does this by putting it in W upon return. Of course don't take my word on this, check the C18 manual to be sure. – Olin Lathrop Oct 2 '11 at 13:12

You're using the PIC18F -- excellent! It fixes many of the quirks of the earlier PC16F. Alas, it still has a few quirks that trip up people used to other processors. I'm pretty sure several of the following pages discuss the PIC-assembly-language version of allocating an array in RAM and indexing the FSR register through that array:

PicList Beginners Checklist http://www.piclist.com/techref/microchip/index.htm

Moving data blocks http://www.piclist.com/techref/microchip/memmove.htm