Sign in to follow this  
PumpkinPieman

Arrays in Assembly (x86)

Recommended Posts

I've been having a little trouble understanding arrays in assembly, primarily having to set the values with the index. What I need to know is a general way of creating an array, pulling data from an array, and setting an array element. right now I'm pretty confused, and any help would be appreciated. Thanks

Share this post


Link to post
Share on other sites
This really only confuses me more. Is there a small example you can give me?

Here's what I'm doing

mov AH, 0
mov AL, firstChar

mov BX, 0
WhileLp1: cmp BX, 8
jge WhileDone1

bt AX, BX
JNC valueFalse1
lea CX, firstCharArr
add CX, BX
mov CX, 1

valueFalse1:

inc BX
jmp WhileLp1
WhileDone1:



I'm trying to break the byte apart and set each value of the array according to if it is 1 or 0, the array is already 0'd out.

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1
Quote:
Original post by PumpkinPieman
Here's what I'm doing...


Is this not working? What results are you getting?


I can't even tell. I can't see anything that's going on in the program, I just assume what I'm writing is working.

Share this post


Link to post
Share on other sites
Yeah, the AT&T syntax probably only confuses things.

Investigate indexed and scaled-index modes.

From those notes ...

movl _foo(%esi,%edi), %eax;

movl _foo(%esi,%edi,2), %eax;

these are transfers from a array named foo to eax (iirc) - AT&T syntax reverses operand order from Intel syntax - ie op src,dest

If you know C or C++, you might want to direct your favorite compiler to output an assembly listing for simple code that uses an array. For example,


int main(void)
{
int array[100];
for (int i=0; i < 100; i++)
{
array[i] = 2*i;
}
return 0;
}



.text
; 1 int main(void)
.type _main,function
_main:
pushl %ebp
movl %esp,%ebp
subl $404,%esp // make space on stack for array
pushl %esi
pushl %edi
; 2 {
.line 2
; 3 int array[100];
; 4 for (int i=0; i < 100; i++)
.line 4
movl $0,-4(%ebp) // index
jmp _$5
_$2:
; 5 {
; 6 array[i] = 2*i;
.line 6
movl -4(%ebp),%edi // use edi as temporary index
movl %edi,%esi
sall $1,%esi
movl %esi,-404(%ebp,%edi,4) // assign to array
_$3:
.line 4
incl -4(%ebp)
_$5:
cmpl $100,-4(%ebp)
jl _$2
; 7 }
; 8 return 0;
.line 8
movl $0,%eax
_$1:
; 9 }
.line 9
popl %edi
popl %esi
leave
ret
_$7:
.size _main,_$7-_main
.globl _main



Share this post


Link to post
Share on other sites
mov CX, 1
In this line, you are setting CX to 1 whereas you want to set the byte of memory at address CX to 1. Thus, you want
mov [CX], 1
Effectively you want to dereference the value of CX, just like dereferencing a pointer.

Unfortunately, in 16-bit assembly you can only dereference certain registers. This includes BX but excludes CX. You thus need to switch your usage of BX and CX.

Share this post


Link to post
Share on other sites
Thus, you need:


mov AH, 0
mov AL, firstChar

mov CX, 0
WhileLp1: cmp CX, 8
jge WhileDone1

bt AX, CX
JNC valueFalse1
lea BX, firstCharArr
add BX, CX
mov [BX], 1

valueFalse1:

inc CX
jmp WhileLp1
WhileDone1:



Note that this uses CX in its more natural guise - as a count register (hence the name CX).

Also, this code can be optimised quite significantly by using more advanced addressing modes.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this