Search code examples
stringassemblyreversedosx86-16

How to print in reverse in assembly language using DOSBox Debug?


This is one of the examples my instructor gave me but I need to find a way to reverse the order of what I input.

Here's the code:

e200 "Name: $"
e300 "Hello, $"
a100
mov ah, 09
mov dx, 200
int 21
mov bx, 400
mov ah, 01
int 21
mov [bx], al
inc bx
cmp bx, 405
jne 10a
mov cl, 24
mov [bx], cl
mov ah, 02
mov dl, 0a
int 21
mov dl, 0d
int 21
mov ah, 09
mov dx, 300
int 21
mov ah, 09
mov dx, 400
int 21
int 20

Output is:

Name: Maria
Hello, Maria

Expected Output (reverse):

Name: Maria
Hello, ariaM

Solution

  • Tested on current lDebug and (creating the executable only) on Microsoft's Debug from MS-DOS version 2 (available under MIT license). This should solve your task.

    f 100 4FF 90
    a 100
     mov ah, 09
     mov dx, 500
     int 21
     mov ah, 0A
     mov dx, 800
     int 21
     mov ah, 09
     mov dx, 600
     int 21
     xor cx, cx
     mov cl, [801]
     mov bx, cx
     add bx, 801
     jcxz 190
    
    a 130
     mov ah, 02
     mov dl, [bx]
     int 21
     dec bx
     loop 130
    
    a 190
     mov ah, 09
     mov dx, 700
     int 21
     mov ax, 4C00
     int 21
    
    e 800 FF 0 0D
    e 500 "Name: $"
    e 600 0D 0A "Hello, $"
    e 700 0D 0A "$"
    g
    q
    
    1. 800 up to below 901 holds a maximum size buffer for interrupt 21h service 0Ah, which we initialise to FF (buffer size 255), 0 (nothing to recall), 0D (indicate end of recallable input).

    2. 500, 600, and 700 contain dollar-terminated messages to be used with interrupt 21h service 09h.

    3. The output loop counter is initialised to CX = CL = length in bytes of input line, as returned by service 0Ah, excluding the final Carriage Return.

    4. The offset to output is initialised to BX = 801 + CX, which is the same as 802 + CX - 1. 802 is the address of the first byte of the returned input. 802 + CX is the address behind the last byte of the returned input. The minus one serves as an adjustment to point at the last byte instead of behind it.

    5. jcxz skips the loop for empty names.

    6. mov dl, [bx] loads a byte into the low half of DX.

    7. Interrupt 21h service 02h is used to output a byte.

    8. dec bx decrements the offset stored in BX.

    9. The loop 130 instruction decrements CX and jumps back if the resulting CX is non-zero.

    10. The f command is to fill a part of the code segment with all nop instructions. Along with the different a commands this allows us to place and use fixed offsets for jump targets in the code, without having to know exactly how long each instruction will be.

    11. Enter the name input, then indicate its end using the Enter key.

    To generate an executable, prepend the command f 100 9FF 0, then instead of the g command run this:

    r bx
     0
    r cx
     900
    n test.com
    w 100
    q