Search code examples
assemblyx86outputmasmirvine32

Read input (a name), store it and output it


I've been trying for a while to input the name (max 20 characters) and output it. If I try to output the name exactly after I input it everything is fine but if I try to output it near the end of the code (check arrows) it outputs nothing. While debuging using the word "train" as input I saw the array_name got the letter "t" at it's first position but in the line where I say "<~~~~array_name goes from "T" to 0 after this lane~~~~" it turns to 0 and I can't find why. Here is my code, I have arrows as comments in the spots that have to do with it. Everything works except this little one.

TITLE Expression calculator (Project_4_a.asm)
; This program ………
INCLUDE Irvine32.inc
    table_size EQU 8d
    name_size EQU 21d ;<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data
    array_number SWORD table_size DUP (?)
    array_name WORD name_size DUP (?) ;<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    string0 BYTE "Enter your name <max 20 characters>:", 0 
    string1 BYTE "Enter a degree for lesson N.", 0
    string2 BYTE ":", 0
    string3 BYTE "Degree for lesson N.", 0
    string4 BYTE "Average deegree <student:", 0
    string5 BYTE ">= ", 0
    counter BYTE 0d
    counter2 BYTE 0d
    average WORD 0d


.code
main PROC
    mov EDX, OFFSET string0
    CALL WriteString
    mov EDX, OFFSET array_name ;<~~~~~~~~~~~~~Read~~~~~~~~~~~~~~~~~
    mov ECX, name_size ;<~~~~~~~~~~~~~~~~~~~~~Read~~~~~~~~~~~~~~~~
    call ReadString ;<~~~~~~~~~~~~~~~~~~~~~~~~Read~~~~~~~~~~~~~~
    ;If i put the 2 lines below it outputs the string correctly.
    ;mov EDX, OFFSET array_name 
    ;CALL WriteString
    call Crlf
    mov ECX, table_size ; ECX=8
    mov EDI, 0d
L1:
    mov EBX, offset array_number ;
    mov EDX, OFFSET string1 ; output
    CALL WriteString ; output
    ADD counter, 1d ; output
    MOVZX EAX, counter ; output
    CALL WriteDec ; output
    mov EDX, OFFSET string2 ; output
    CALL WriteString ; output
    CALL ReadDec ; input
    ADD EBX,EDI ; 
    ADD EDI, type array_number
    MOV [EBX], EAX ; fill array <~~~~array_name goe from "T" to 0 after this lane~~~~
    CALL Crlf
    LOOP L1


    mov ECX, table_size
    mov AX, 0d
    mov ESI, offset array_number
L2:
    sub ECX, 1
    ADD AX, [esi + ECX * TYPE array_number]
    add ECX, 1
    LOOP L2 
    SHR AX,3
    MOV average, AX ;


    MOV ECX, table_size
L3:
    mov EDX, OFFSET string3 ; output
    CALL WriteString ; output
    MOV EAX, ECX  ; output
    CALL WriteDec ; output
    mov EDX, OFFSET string2 ; output
    CALL WriteString ; output
    mov ESI, offset array_number
    sub ECX,1
    MOV BX, [esi + ECX * TYPE array_number]
    add ECX,1
    MOVZX EAX, BX
    CALL WriteInt
    CALL Crlf
    LOOP L3

    mov EDX, OFFSET string4 ; output
    CALL WriteString ; output

    mov EDX, OFFSET array_name ; output ;<~~~~~~~~~~~~~write~~~~~~~~~~~~~~~~~~~~~~
    CALL WriteString ; output ;<~~~~~~~~~~~~~~~~~~~~~~~write~~~~~~~~~~~~~~

    mov EDX, OFFSET string5 ; output
    CALL WriteString ; output
    MOVZX EAX, average ; output
    CALL WriteDec ; output
    CALL Crlf


exit
main ENDP
END main

Solution

  • Okay, I see this uses a library associated with a book that I don't have.

    This is a tricky bug. The problem is that you declared array_number as an array of 2-byte words. In the 8th iteration through the problematic loop, the EBX register will have a value array_number + 14. The instruction MOV [EBX], EAX then executes the last time. This instruction moves 4 bytes. So it overwrites the 2 bytes beyond array_number, which are the first two bytes of array_name. Moreover, these are the high 2 bytes of whatever number you input, so unless you type an input bigger than 255, they will be 0 as you are observing.

    I think you meant either to declare array_number to be of type SDWORD or else the MOV instruction should be copying only 2 bytes, not 4.

    Incidentally, your library is documented here. This is the info I needed to make sense of your program.