Search code examples
arraysloopsassemblycpu-registersy86

Trouble creating an array loop in Y86 Assembly


I need to create a program that sorts an array of integers into ascending order. Simple enough problem in C, and the code is given to us.

void bubble(int *data, int count)
{
int i, last;
for(last = count‐1; last>0;last‐‐)
{
for(i=0;i<last;i++)
if
(data[i+1] < data[i])
{
/* Swap adjacent elements */
int t=data[i+1];
data[i+1]=data[i];
data[i]=t;
}
}
}

but when I try to implement it into assembly, I get either

Error on line 90: Invalid line
Line 90, Byte 0x00d0: .comm *data,20,4      //data = memory location

or, if I comment that line out (I don't think I should) I get this

Error on line 39: Expecting ')'
Line 39, Byte 0x005a:   mrmovl (%edx,%ebx,4),%eax   //%eax = data[i]
Error on line 41: Expecting ')'
Line 41, Byte 0x0066:   mrmovl 4(%edx,%ebx,4),%edi  //%edi = data[i++]
Error on line 46: Expecting ')'
Line 46, Byte 0x0073:   mrmovl 4(%edx,%ebx,4),%edi  //%edi = data[i++]
Error on line 47: Expecting ')'
Line 47, Byte 0x0079:   rmmovl %edi, (%edx,%ebx,4)  //data[i] = data[i++]
Error on line 48: Expecting ')'
Line 48, Byte 0x007f:   rmmovl %eax, 4(%edx,%ebx,4) //data[i++] = data[i]

The following is my code as it stands:

    .pos 0

init:   irmovl Stack, %esp  //Set up stack pointer
    irmovl Stack, %ebp  //Set up base pointer
    call main       //call main program
    halt            //Terminate program

bubble: pushl %ebp      //setup
    rrmovl %esp, %ebp

    pushl %edx      //declaring *data
    mrmovl 8(%ebp), %edx        
    pushl %ecx      //declaring count
    mrmovl 12(%ebp), %ecx   
    pushl %ebx      //declaring i
    pushl %esi      //declaring last
    pushl %edi
    pushl %eax
    irmovl $1, %edi     //%edi = 1

    rrmovl %ecx,%esi    //last=count
    subl %edi,%esi      //last--

L1: 
    irmovl $0, %edi     //%edi = 0
    subl %edi,%esi      //last -= 0
    jle L9          //ends loop if last <= 0

    irmovl $0, %ebx     //i = 0
L2:
    rrmovl %ebx, %edi   //%edi = copy of i
    subl %esi,%edi      //%edi = i-last
    jge L8          //ends loop if i >= last

    mrmovl (%edx,%ebx,4),%eax   //%eax = data[i]
    irmovl $1, %edi         //%edi = 1
    mrmovl 4(%edx,%ebx,4),%edi  //%edi = data[i++]

    subl %eax,%edi      //%edi = data[i++]-data[i]
    jge L7          //cancel if statement if data[i++]>=data[i]

    mrmovl 4(%edx,%ebx,4),%edi  //%edi = data[i++]
    rmmovl %edi, (%edx,%ebx,4)  //data[i] = data[i++]
    rmmovl %eax, 4(%edx,%ebx,4) //data[i++] = data[i]

L7:
    irmovl $1, %edi     //%edi = 1
    addl %edi,%ebx      //i++
    jmp L2          //go to beginning of loop
L8:
    irmovl $1, %edi     //%edi = 1
    subl %edi,%esi      //last--
    jmp L1
L9:
    popl %ebx       //finish
    popl %esi
    popl %edi
    popl %eax
    popl %ebp

    ret




main:   pushl %ebp      //setup
    rrmovl %esp, %ebp

    pushl %ebx      //declaring *data
    mrmovl data, %ebx   
    pushl %esi      //declaring count
    mrmovl count, %esi  

    rmmovl %ebx, (%esp) //move data to be used by bubble
    rmmovl %esi, 4(%esp)    //move count to be used by bubble

    call bubble

    popl %ebx       //finish
    popl %esi
    popl %ebp

    ret


.comm data,20,4     //data = memory location
.align 4
count:  .long 5     //count = memory location 
data:   .long 2     //data array assignment
    .long 1
    .long 3
    .long 5
    .long 4

.pos 0x200
Stack: .long 0

Solution

  • y86 does not support the full x86 effective address syntax with the index and scale, it only allows displacement(base). You have to perform the address calculation yourself.

    The y86 assembler doesn't support .comm either, just define your data using .long