Reading a C array from Assembly

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
M-374 LX
Very interested
Posts: 61
Joined: Mon Aug 11, 2008 10:15 pm
Contact:

Reading a C array from Assembly

Post by M-374 LX » Sat Mar 22, 2014 5:14 pm

Is this the right way to read the value at a position of a C array from Assembly?

In this case, d1 determines the position to be read and the value is stored in d0:

Code: Select all

lea array, %a0
adda %d1, %a0
move.l (%a0), %d0
A possible declaration in C is:

Code: Select all

const u32 array[] = {1, 2, 3, 4, 5};

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Re: Is whis the right way?

Post by MintyTheCat » Sat Mar 22, 2014 5:38 pm

M-374 LX wrote:Is this the right way to read the value at a position of a C array from Assembly?

In this case, d1 determines the position to be read and the value is stored in d0:

Code: Select all

lea array, %a0
adda %d1, %a0
move.l (%a0), %d0
A possible declaration in C is:

Code: Select all

const u32 array[] = {1, 2, 3, 4, 5};
LEA can be used to load the address of a section of Memory (W, L).

That Memory could be a C-Array.

Under 68K the format is Opeation.Size Source, Destination for Ops such as Move.
I see what you are trying to achive by that adda but you can use an offset within the instruction using one of the 68K's Modes - I forget the name of it but something such as move.W (d0,a0),d1 and I may have the Operands mixed up here but check the 68K Programmers Reference Manual or other 68K Reference for Ops.

Cheers,

Minty.

r57shell
Very interested
Posts: 478
Joined: Sun Dec 23, 2012 1:30 pm
Location: Russia
Contact:

Post by r57shell » Sat Mar 22, 2014 6:08 pm

First, you should calculate offset properly.
Then, read from this offset.
Assuming u32 is 4 bytes size, correct code is:

Code: Select all

lea array, a0
add.w d0,d0 ; multiply by 4
add.w d0,d0 ; you can replace this part by single lsl.w #2,d0
move.l (a0,d0.w),d1
But don't forget, that I was using d0 as word.
So, if you have only byte, you need

Code: Select all

moveq #0,d1 ; fast clear (or clr.w d1, or clr.l d1)
move.b d0,d1
lea array, a0
add.w d1,d1 ; multiply by 4
add.w d1,d1
move.l (a0,d1.w),d1
or try
move.l (a0,d0.b),d1
but I'm not sure that it's existing.
Image

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Post by MintyTheCat » Sat Mar 22, 2014 8:18 pm

r57shell wrote:
or try
move.l (a0,d0.b),d1
but I'm not sure that it's existing.
Yes, you gave a more full example - cheers. I would think not considering that the 68K is a Word Machine but then it may be limited in number as an Offset - again I would have to check the Refs.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Mar 22, 2014 9:35 pm

Byte indexing doesn't exist, just word and long. Don't forget that a word index is SIGNED, so it's not 0 to 65535, it's -32768 to 32767. If you need an unsigned index, zero extend it to a long and use a long index instead. If your index is greater than 16K, you need to use a long anyway since *4 will exceed a word.

Code: Select all

    moveq #0,d1
    move.w d0,d1
    add.l d1,d1
    add.l d1,d1
    lea array,a0
    move.l 0(a0,d1.l),d0
Note that if the index will not be > than 16K, use word operations since add.w is faster than add.l (because the 68000 uses a word width ALU).

With the 68020 and better, one thing Motorola added was the ability to scale the index, like 0(a0,d1.l*4) for addressing long values in memory. They added *1 (default for backwards compatibility), *2, *4, and *8. That would have been handy on the 68000 as you'd avoid needing to multiply the index by the size of the value being accessed.

MintyTheCat
Very interested
Posts: 484
Joined: Sat Mar 05, 2011 11:11 pm
Location: Berlin, Germany

Post by MintyTheCat » Sat Mar 22, 2014 10:30 pm

To be honest, I never ever use Mulu and Mul on the 68K as it's just too expensive. But yes, it would have been a lot easier as the first thing anyone has to do is to double the vale for the Index.

Post Reply