Search code examples
assemblydosx86-16tasmdosbox

Assembly - Program works like expected, but when ran a second time, prints gibberish


I'm making a program in TASM assembly (i honestly have no idea if it's 16 bit, x86, 64 bit maybe 8086?. I'm using TASM inside DOSBox for assembling, linking, and testing.

The user inputs characters until the user presses Enter key. then echos what they typed back to the console. This is my code:

IDEAL
model small
STACK 100h

DATASEG
wholeinput db 00

CODESEG
start:

mov ax,@data
mov ds,ax
    mov bx, 0 ; bx is the counter

    input:
    mov ah, 1 ; input moves the input to al
    int 21h

    cmp al, 13 ; 0xD is enter key
    je enterPressed ; if its not 'enter' then continue
    add [wholeinput+bx], al ; add the given character to the end of the string

    inc bx    ; inc counter of string length
    jmp input ; continue loop


    enterPressed:
    add [wholeinput+bx], '$' ; add to the last byte of the thing a string terminator
    mov ah, 9
    mov dx, offset wholeinput ; print the whole thing
    int 21h


exit:
mov ax,4c00h
int 21h
END start

The first time I run the program it works as expected. When I run the same program a second time with the same input it prints gibberish to the console.

My theory is that the memory from my previous run is somehow copied to the next run. this could be a very stupid thing to say but I'm a noob...

Screenshot

What could be my problem? How can I solve it?

Edit: Thanks to Mike Nakis and Peter Cordes for this solution:
The problem was that I did not reserve enough space for the input.

wholeinput db 00

only reserve one byte. Fix:

wholeinput db 100 dup(0)


Solution

  • Your theory (that memory from a previous run is still there) is probably correct, not a stupid idea at all.

    db 00 will only reserve space for a single byte. So you're writing past the end of your DATA segment for any input of more than 0 bytes. (Just pressing Enter right away will lead to your program storing a '$' to that byte.)

    You need db 100 dup(0) for an array of 100 zeros. See What does `dup (?)` mean in TASM?

    Why reserving insufficient space causes this particular kind of behavior, I do not know, and to tell you the truth, this is not the behavior I would expect from this type of mistake. But then again, in our profession, all kinds of weird things happen, and when you see what the most likely cause of the problem is, you can either quickly fix it and proceed with your life, or you can spend hours troubleshooting to try and figure out precisely why the particular behavior was observed. The choice is yours.


    I am not sure whether TASM was ever made for anything other than 16-bit; In any case, the code definitely looks 16-bit, and this is also definitely being assembled by TASM as 16-bit, otherwise the model small clause would be giving an error, as this clause only exists in 16-bit mode.