Search code examples
assemblymasmirvine32

Macro in loop works once, then doesn't


Procedure ReadVal should loop and ask the user to input 10 integers (AS STRINGS), ultimately storing each in an array. ReadVal uses the macro getString and it works the first time through. Then the other 9 times, it prints "Please enter an unsigned integer:" but does not stop to allow the user to enter a value. So, it's definitely calling the macro, but why does it not stop and wait for input the next 9 times.

INCLUDE Irvine32.inc
LEN = 10    ; Number of elements in array.

getString   MACRO   buffer, size
    push eax
    push ecx
    push edx
    mov edx,    OFFSET  userMsg_2
    call WriteString
    mov edx, buffer             ; buffer passed by reference, so no OFFSET req'd.
    mov eax, size
    mov ecx, [eax]              ; Dereference sizeElem to ecx counter.
    call ReadString
    pop edx
    pop ecx
    pop eax
ENDM

.data
userMsg_2   BYTE        "Please enter an unsigned number: ",0
array DWORD LEN dup(?)
    arLength    DWORD   LEN
    sizeElem    BYTE    11      ; Number of digits allowed in. reading ints as strings.
    holder  DWORD   ?           ; Temp memory location for storing string input/output.
.code
main PROC
    push OFFSET array
    push OFFSET arLength
    push OFFSET sizeElem
    push OFFSET holder
    call ReadVal
exit
main ENDP

ReadVal PROC
    push ebp
    mov ebp, esp
    push ecx
    mov esi, [ebp+20]               ; esi has starting address of array.
    mov eax, [ebp+16]               ; @arLength
    mov ecx, [eax]                  ; ecx gets arLength.
    cmp ecx, 0
    je L2
L1:
    getString [ebp+8], [ebp+12]  ; [ebp+8] gets the user inputted string.
    mov esi,    [ebp+8]          ; mov string in holder into array[esi].
    add esi, TYPE   DWORD
    loop L1
L2:
    pop ecx
    pop ebp
    ret 16
ReadVal ENDP
END main

Solution

  • I think the problem is that ReadString expects the value in ECX to be a DWORD. Giving it a number as a BYTE is confusing it. Declaring sizeElem as a DWORD solves the issue.

    You might want to declare holder as using BYTEs instead of DWORD while you're at it too, I think that's more typical of string storage.