Search code examples
arrayssortingassemblyx86irvine32

ASSEMBLY - output an array with 32 bit register vs 16 bit


I'm was working on some homework to print out an array as it's sorting some integers from an array. I have the code working fine, but decided to try using EAX instead of AL in my code and ran into errors. I can't figure out why that is. Is it possible to use EAX here at all?

    ; This program sorts an array of signed integers, using 
    ; the Bubble sort algorithm. It invokes a procedure to 
    ; print the elements of the array before, the bubble sort, 
    ; once during each iteration of the loop, and once at the end.

    INCLUDE Irvine32.inc
    .data
    myArray   BYTE       5, 1, 4, 2, 8
    ;myArray    DWORD       5, 1, 4, 2, 8
    currentArray BYTE   'This is the value of array: ' ,0
    startArray BYTE 'Starting array. ' ,0
    finalArray BYTE 'Final array. ' ,0
    space BYTE ' ',0                                                ; BYTE

    .code
    main PROC

        MOV EAX,0                                       ; clearing registers, moving 0 into each, and initialize
        MOV EBX,0                                       ; clearing registers, moving 0 into each, and initialize
        MOV ECX,0                                       ; clearing registers, moving 0 into each, and initialize
        MOV EDX,0                                       ; clearing registers, moving 0 into each, and initialize
        PUSH EDX                        ; preserves the original edx register value for future writeString call
        MOV EDX, OFFSET startArray  ; load EDX with address of variable
        CALL writeString                ; print string
        POP EDX                         ; return edx to previous stack
        MOV ECX, lengthOf myArray           ; load ECX with # of elements of array
        DEC ECX                               ; decrement count by 1


    L1: 
        PUSH ECX                             ; save outer loop count
        MOV ESI, OFFSET myArray          ; point to first value

    L2: 
        MOV AL,[ESI]              ; get array value
        CMP [ESI+1], AL               ; compare a pair of values
        JGE L3                        ; if [esi] <= [edi], don't exch
        XCHG AL, [ESI+1]             ; exchange the pair
        MOV [ESI], AL
        CALL printArray             ; call printArray function
        CALL crlf
    L3: 
        INC ESI                       ; increment esi to the next value
        LOOP L2                   ; inner loop
        POP ECX                   ; retrieve outer loop count
        LOOP L1                   ; else repeat outer loop
        PUSH EDX                        ; preserves the original edx register value for future writeString call
        MOV EDX, OFFSET finalArray  ; load EDX with address of variable
        CALL writeString                ; print string
        POP EDX                         ; return edx to previous stack
        CALL printArray

    L4 : ret 



    exit
    main ENDP


    printArray PROC uses ESI ECX

    ;myArray loop
        MOV  ESI, OFFSET myArray                                ; address of myArray
        MOV  ECX, LENGTHOF myArray                              ; loop counter (5 values within array)          
        PUSH EDX                        ; preserves the original edx register value for future writeString call
        MOV EDX, OFFSET currentArray    ; load EDX with address of variable
        CALL writeString                ; print string
        POP EDX                         ; return edx to previous stack

    L5 :
        MOV  AL, [ESI]                                              ; add an integer into eax from array
        CALL writeInt   
        PUSH EDX                        ; preserves the original edx register value for future writeString call
        MOV EDX, OFFSET space
        CALL writeString
        POP EDX                         ; restores the original edx register value  
        ADD  ESI, TYPE myArray                                  ; point to next integer     
        LOOP L5                                             ; repeat until ECX = 0 
        CALL crlf

    RET 

        printArray ENDP

        END main
        END printArray

    ; output:
    ;Starting array. This is the value of array: +1 +5 +4 +2 +8

    ;This is the value of array: +1 +4 +5 +2 +8

    ;This is the value of array: +1 +4 +2 +5 +8

    ;This is the value of array: +1 +2 +4 +5 +8

    ;Final array. This is the value of array: +1 +2 +4 +5 +8

As you can see the output sorts the array just fine from least to greatest. I was trying to see if I could move AL into EAX, but that gave me a bunch of errors. Is there a work around for this so I can use a 32 bit register and get the same output?


Solution

  • Using EAX is definitely possible, in fact you already are. You asked "I was trying to see if I could move AL into EAX, but that gave me a bunch of errors." Think about what that means. EAX is the extended AX register, and AL is the lower partition of AX. Take a look at this diagram:image of EAX register . As you can see, moving AL into EAX using perhaps the MOVZX instruction would simply put the value in AL into EAX and fill zeroes in from right to left. You'd be moving AL into AL, and setting the rest of EAX to 0. You could actually move everything into EAX and run the program just the same and there'd be no difference because it's using the same part of memory.

    Also, why are you pushing and popping EAX so much? The only reason to push/pop things from the runtime stack is to recover them later, but you never do that, so you can just let whatever is in EAX at the time just die.