Sergei Gaidachevsky
Sergei Gaidachevsky

Reputation: 29

Assembly Input up to 8 chars to string and output the reversing string

I have a homework question to get from user up to 8 char in the string in a new line and print it on reverse

I wrote a code that should take every bit from string and put it in the stack and then take it back to the string so it's will be in reversing and print it in the new line. But when I run the file it's just stuck on input and does't give me to do something

I'm new to assembly, we use tasm1~1.4.

there is my code:

    STA SEGMENT STACK
        DB 100H DUP (0)
    STA ENDS

    DATA SEGMENT
        MSG1 DB 'ENTER STRING (Maximum is 8) : $'
        MSG2 DB 'REVERS IS : $'
        ISTR DB 10 DUP(0)
    DATA ENDS

    CODE SEGMENT
        ASSUME CS:CODE,DS:DATA,SS:STA
    MAIN:
        MOV AX, DATA
        MOV DS, AX
        LEA DX, MSG1
        MOV AH, 09H
        INT 21H
        MOV DX, 0
    ;INPUT
        MOV DX, OFFSET ISTR
        MOV AH, 0AH
        INT 21H
        MOV SI, DX
        MOV CL, [SI+1]
        ADD SI, 2
        MOV DX, 0
        MOV BL, CL
    TOSTACK:
        MOV DX, [SI]
        PUSH DX
        INC SI
        LOOP TOSTACK
        MOV DL, 10
        MOV AH, 02H
        INT 21H
        LEA DX, MSG2
        MOV AH, 09H
        INT 21H
        MOV DX, 0
        MOV CL, BL
        MOV SI, 2
    FROMSTACK:
        POP DX
        MOV AH, 02H
        INT 21H
        INC SI
        LOOP FROMSTACK

        MOV AX, 4C00H
        INT 21H

    CODE ENDS
        END MAIN

Upvotes: 1

Views: 637

Answers (1)

Sep Roland
Sep Roland

Reputation: 39316

But when I run the file it's just stuck on input ...

This is because when using the DOS input function 0Ah, you need to tell DOS beforehand the size of your input buffer. With a definition like ISTR DB 10 DUP(0) you've actually requested no buffer at all!
A correct definition in your program is

ISTR DB 9, 0, 9 DUP(0)

The 1st byte specifies the size of the input buffer. Put it at DesiredNumberOfCharacters + 1.
The 2nd byte specifies how many characters the buffer already contains. Put it at zero.

You can find much more information about this DOS function in another post of mine How buffered input works.

Once your input works, you need to fix a few problems in the TOSTACK part of your program:

  • The LOOP instruction depends on the whole CX register, but you only filled CL which is the low byte of CX. Simply add mov ch, 0.
    This obviously means that you also need to copy to BX instead of to BL in preparation for the FROMSTACK part.
  • Because the user could have chosen to not supply any character at all, your program needs to be prepared for this case. A mere jcxz EXIT will suffice.
  • Each character from the input buffer is held in a byte. Your code should thus not be reading words.

.

    mov     si, offset ISTR + 1
    mov     cl, [si]     ; Characters read 0, 1, 2, ... 8
    mov     ch, 0
    jcxz    EXIT
    mov     bx, cx       ; Save count
TOSTACK:
    inc     si
    mov     dl, [si]     ; This is a byte
    push    dx           ; Don't care about high byte in DH
    loop    TOSTACK

    ...

    mov     cx, bx       ; Restore count ( is GT 0 )
FROMSTACK:
    pop     dx           ; Still don't care about DH
    mov     ah, 02h
    int     21h
    loop    FROMSTACK
EXIT:
    mov     ax, 4C00h
    int     21h

Getting rid of the slow LOOP instruction is easy:

    mov     si, offset ISTR + 1
    mov     cl, [si]     ; Characters read 0, 1, 2, ... 8
    mov     ch, 0
    jcxz    EXIT
    mov     bx, cx       ; Save count
TOSTACK:
    inc     si
    mov     dl, [si]     ; This is a byte
    push    dx           ; Don't care about high byte in DH
    dec     cx
    jnz     TOSTACK

    ...

FROMSTACK:
    pop     dx           ; Still don't care about DH
    mov     ah, 02h
    int     21h
    dec     bx
    jnz     FROMSTACK
EXIT:
    mov     ax, 4C00h
    int     21h

Upvotes: 2

Related Questions