Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Indexing an array in assembly

Status
Not open for further replies.

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
edaboard,
I have a project that contains a main.c and an asm.s.

In the main.c I declare an array as:
volatile unsigned int numbers[10];

In the asm.s is:
GLOBAL _numbers

In the asm.s I can index that array with
movf _numbers + 1,0,0
movf _numbers + 2,0,0
etc.
works fine.

But if I try to index it with a variable
ex: movf _numbers + variable,0,0
it compiles but the indexing doesn't happen?

jerryd
 

FvM

Super Moderator
Staff member
Advanced Member level 7
Joined
Jan 22, 2008
Messages
51,217
Helped
14,653
Reputation
29,584
Reaction score
13,797
Trophy points
1,393
Location
Bochum, Germany
Activity points
292,751
Read instruction set manual about indirect addressing. There's no simple indexed addressing in 8 bit PIC.

Review the compiler generated code for a respective operation.
 

betwixt

Super Moderator
Staff member
Advanced Member level 7
Joined
Jul 4, 2009
Messages
15,845
Helped
5,093
Reputation
10,211
Reaction score
4,960
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
134,146
You have to do the index calculation yourself. An array, no matter whether single or multi-dimensional still 'physically' exists as a flat list in memory. For example, an int typically needs two bytes in an 8-bit PIC so each int you store needs two memory locations. Your array of 10 ints needs 20 memory locations and each indexed number will be at (2 * index) + address of the array. So to do it in your code, substitute your variable for the index number and do the calculation to find the address the variable is stored. It will occupy that address and the one after it.

Brian.
 

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
betwixt,
Thanks for the reply.
I understand what you are saying. So assuming there are 2 bytes per array location I tried this simple test:

This worked:
movf _numbers + 0,0,0
movf _numbers + 2,0,0
movf _numbers + 4,0,0
movf _numbers + 6,0,0

This didn't:
movlw 0
movwf index,0
movf _numbers + index,0,0

movlw 2
movwf index,0
movf _numbers + index,0,0

movlw 4
movwf index,0
movf _numbers + index,0,0

movlw 6
movwf index,0
movf _numbers + index,0,0

jerryd
 

Aussie Susan

Advanced Member level 5
Advanced Member level 5
Joined
Jan 5, 2015
Messages
1,504
Helped
407
Reputation
814
Reaction score
448
Trophy points
1,363
Activity points
17,694
As others have said, you need to understand the instruction set of the PIC you are using. The assembler can do the arithmetic for '_numbers + 2' for you and generate the correct binary code. However it can't do the "_numbers + index" as the instruction set simply does not have a suitable single instruction.
Write the code in C, compile it and look at the assembler that it generates and then use that.
(Of course this begs the question why not just do this in C.)
Susan
 

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
Aussie Susan,
Thanks for chiming in.

In another post you suggested I do this in C. As I stated then "I have written this program in MicroC and MicroBasic while teaching my grandson about coding."

I have most of it working in assembly but am stuck at this point.

I looked around my folder and read what I could on line but can't figure out how to find the assembly code created by the assembler.

jerryd
 

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
edaboard,
Thanks Susan but I'm actually doing this with MPLAB X XC8.
jerryd
 

betwixt

Super Moderator
Staff member
Advanced Member level 7
Joined
Jul 4, 2009
Messages
15,845
Helped
5,093
Reputation
10,211
Reaction score
4,960
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
134,146
All you have to do is add 'index' and the _numbers together with assembler instructions. Looking at the listing from a high level language should help but might for operational reasons include other code that you don't need.
The bottom line is that as already explained, there is no single instruction that fetches two values from different memory addresses and adds them together, you have to break it into single steps.

movf index,w
addwf _numbers,f

will leave _numbers holding the total of the two. In your example that should work but be careful if the result exceeds 0xFF, as you will exceed 8-bits as the result and have to 'carry' to the next address.

Brian.
 

KlausST

Super Moderator
Staff member
Advanced Member level 7
Joined
Apr 17, 2014
Messages
23,506
Helped
4,758
Reputation
9,537
Reaction score
5,172
Trophy points
1,393
Activity points
155,893
Hi,

"teaching my grandson"

But what do you teach him? Assembler or C?

If assembler, then the instruction set is your - and your grandson´s - reference.
In assembler each assembler_instruction exactly refers to one machine_instruction.
So you can only use instruction that the microcontroller understands.
Assembler depends on the microcontroller you use, every microcontroller provides different assmbler (machine) instructions. If you write an assembler code for one microcontroller you usually can not use the same code for a different microcontroller.

In opposite at C:
Each C instruction becomes compiled, resulting in multiple machine instructions.
C is a machine_independent language. Thus (ideally) you may use the same C code for different microcontrollers.
But the C code needs to be compiled for the according microcontroller, resulting in different code for different microcontrollers.

Because of this, I recommend to start teaching your grandson with one language only, either C or ASM.
It´s too much confusing, because they are different coding concepts.
Combine them later - when necessary.


Klaus
 

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
betwixt,
I tried several iterations of your suggestion but none worked. Seems like indexing has to be done in one operation.

jerryd
 

Aussie Susan

Advanced Member level 5
Advanced Member level 5
Joined
Jan 5, 2015
Messages
1,504
Helped
407
Reputation
814
Reaction score
448
Trophy points
1,363
Activity points
17,694
Then you need to show us ALL of your actual code so we can see where you are going wrong.
Susan
 

jerryd

Junior Member level 3
Junior Member level 3
Joined
Feb 4, 2013
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,496
eadboard,
A little reading of indirect addressing for a pic18 led me to the solution.
Using FSR and INDF it's just pointer math.

LFSR 0, _numbers // Set FSR0 pointing to the top of _numbers
movf INDF0,0,0 // get the first value from _numbers

To get the next value all I have to do is:
incr FSRO,1,0 // using the arguments avoids a compiler warning
incr FSRO,1,0 // using the arguments avoids a compiler warning
movf INDF0,0,0 // get the next value from _numbers

Thanks for all the replies.
I'm sure I'll be back with more questions.
jerryd
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top