Search code examples
assemblyx86masm32irvine32

Assembly newbie requesting help: signed integer division + "truncating to an integer"


I asked a question regarding this code several days ago, so some of you may find it familiar. For those of you who do not find it familiar, what this code is supposed to do is request 25 signed integers from the user and store them into an array; this is done via the requestSignedInts subroutine (I'm pretty sure this part is working correctly). Afterwards, a "calcMean" subroutine is supposed to add up all of the values in the array, divide them by the number of elements in the array, and then "truncate the result to an integer". This is where I'm stuck. I attempted to write a calcMean subroutine that would do what I described just now, but cannot seem to figure out how to do the division properly. On top of that, I'm not even sure if what I currently have in my calcMean subroutine would work properly. Can anyone provide assistance?

INCLUDE    c:\irvine\irvine32.inc
INCLUDELIB c:\irvine\irvine32.lib
INCLUDELIB c:\masm32\lib\user32.lib
INCLUDELIB c:\masm32\lib\kernel32.lib

.data
theSINTArray BYTE 25 dup(?)
lengthOfArray BYTE ?
indexCounter BYTE 0              
prompt BYTE "Please enter a value: ",0


.CODE

main PROC

    call    requestSignedInts
    call    calculateMean
    exit

main ENDP

requestSignedInts PROC

    mov     edx, offset theSINTArray
Next:
    push    edx                                        
    mov     edx,OFFSET prompt                          
    call    WriteString                                
    call    ReadInt
    pop     edx 
    mov     [edx], al
    inc     edx
    cmp     edx, offset theSINTArray + 25
    jb      Next
    ret

requestSignedInts ENDP


calculateMean PROC

push ecx
mov    ecx,lengthOfArray - theSINTArray ; Determine array length    
xor    eax, eax                         ; Clear EAX
mov    esi, OFFSET theSINTArray         ; Starting point for index into array
calcMean:
movsx  edx, byte ptr[esi]               ; Sign extended move a byte into EDX
add    eax, edx                         ; Accumulate in EAX
inc    esi                              ; Increment source pointer to the next element
loop   calcMean                         ; or cmp esi,endOfArray / jb, then you wouldn't need to touch ecx

mov    ecx,lengthOfArray - theSINTArray ; Determine array length    
cdq                                     ; sign-extend eax into edx:eax
idiv   ecx                              ; Divide edx:eax by ecx
                                        ; eax now contains the integer and edx contains
                                        ; the remainder.
pop    ecx
ret

calculateMean ENDP

END     main

Solution

  • It seems to me that you might be missing the function of idiv as brought out in the comments. Why not:

    calculateMean PROC
    
    push ecx
    mov    ecx,lengthOfArray - theSINTArray ; Determine array length    
    xor    eax, eax                         ; Clear EAX
    mov    esi, theSINTArray                ; Starting point for index into array
    calcMean:
    movsx  edx, byte ptr[esi]               ; Sign extended move a byte into EDX
    add    eax, edx                         ; Accumulate in EAX
    inc    esi                              ; Increment source pointer to the next element
    loop   calcMean                         ; or cmp esi,endOfArray / jb, then you wouldn't need to touch ecx
    
    mov    ecx,lengthOfArray - theSINTArray ; Determine array length    
    cdq                                     ; sign-extend eax into edx:eax
    idiv   ecx                              ; Divide edx:eax by ecx
                                            ; eax now contains the integer and edx contains
                                            ; the remainder.
    pop    ecx
    ret
    
    calculateMean ENDP
    

    You already know the length of the list, you simply need to clear edx and divide by ecx. This also properly uses a movsx to do a sign extended move of a byte (from your array) into a 32 bit register (edx). The total is accumulated into eax and, finally, we sign extend and divide.