I have a very simple problem that i need to achieve. First you enter a string, the first output should copy the last letter of the string and replace the first letter of the string and then the last letter should be replace with the first letter. The second output should capitalize the first letter of the string. I've already did the second output, my problem now is the first output. Please see the expected result below.
Expected Result
Enter string: jon jones
son jonej
Jon jones
Current Code
.MODEL SMALL
.STACK 100H
.DATA
INPUT_STRING DB 10,13,"Enter string: $"
USER_INPUT_STRING DB 80 DUP('$')
BREAKLINE DB 10, 13, "$"
.CODE
MOV AX, @DATA
MOV DS, AX
LEA DX,INPUT_STRING
MOV AH,09H
INT 21H
LEA DX, USER_INPUT_STRING
MOV AH, 0AH
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
SUB USER_INPUT_STRING + 2, 32 ;Capitalize
MOV AH, 02H
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
LEA DX, USER_INPUT_STRING + 2 ;Output of capitalize
MOV AH, 09H
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
MOV AH, 4CH
INT 21H
END
allowed commands
mov, lea, int, inc, dec, add, sub, proc, re, db
The buffer of Int 21/AH=0Ah
has three parts: size, length, string. The size is the maximal size of the string and must be initialized.
Change
USER_INPUT_STRING DB 80 DUP('$')
to
USER_INPUT_STRING DB 80, 0, 80 DUP('$')
Consider, that the string starts at USER_INPUT_STRING + 2
. There is its first character. After you have entered the string, you will find the length of the string you have entered at USER_INPUT_STRING + 1
, in this case 09h
. So, you'll find the last character of the entered string at USER_INPUT_STRING + 2 + (9 - 1)
. Use registers to swap the values at those memory addresses:
.MODEL SMALL
.STACK 100H
.DATA
INPUT_STRING DB 13,10,"Enter string: $"
USER_INPUT_STRING DB 80, 0, 80 DUP('$')
BREAKLINE DB 13, 10, "$"
.CODE
MOV AX, @DATA
MOV DS, AX
LEA DX,INPUT_STRING
MOV AH,09H
INT 21H
LEA DX, USER_INPUT_STRING
MOV AH, 0AH
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
MOV AL, USER_INPUT_STRING + 2
XOR CX, CX
MOV CL, USER_INPUT_STRING + 1
MOV BX, OFFSET USER_INPUT_STRING + 2
ADD BX, CX
DEC BX
MOV AH, [BX]
MOV [BX], AL
MOV USER_INPUT_STRING + 2, AH
LEA DX, USER_INPUT_STRING + 2
MOV AH, 09H
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
MOV AX, 4C00H
INT 21H
END
The only way to avoid the square brackets, I see in the use of LODSB
and MOVSB
:
.MODEL SMALL
.STACK 100H
.DATA
INPUT_STRING DB 13,10,"Enter string: $"
USER_INPUT_STRING DB 80, 0, 80 DUP('$')
BREAKLINE DB 13, 10, "$"
.CODE
main PROC
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
LEA DX,INPUT_STRING
MOV AH,09H
INT 21H
LEA DX, USER_INPUT_STRING
MOV AH, 0AH
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
CALL swap
LEA DX, USER_INPUT_STRING + 2
MOV AH, 09H
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
MOV AX, 4C00H
INT 21H
main ENDP
swap PROC
LEA DI, USER_INPUT_STRING + 2
MOV AL, USER_INPUT_STRING + 1
MOV AH, 0
SUB AL, 1
ADD DI, AX
MOV SI, DI
LODSB
MOV AH, USER_INPUT_STRING + 2
XCHG AL, AH
STOSB
MOV USER_INPUT_STRING + 2, AH
RET
swap ENDP
END main
In EMU8086 and in TASM (not in MASM) you can also use the special preprocessor arithmetic: USER_INPUT_STRING + 2 + BX - 1
:
.MODEL SMALL
.STACK 100H
.DATA
INPUT_STRING DB 13,10,"Enter string: $"
USER_INPUT_STRING DB 80, 0, 80 DUP('$')
BREAKLINE DB 13, 10, "$"
.CODE
main PROC
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
LEA DX,INPUT_STRING
MOV AH, 09H
INT 21H
LEA DX, USER_INPUT_STRING
MOV AH, 0AH
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
CALL swap
LEA DX, USER_INPUT_STRING + 2
MOV AH, 09H
INT 21H
LEA DX, BREAKLINE
MOV AH, 09H
INT 21H
MOV AX, 4C00H
INT 21H
main ENDP
swap PROC
MOV AH, USER_INPUT_STRING + 2
MOV BL, USER_INPUT_STRING + 1
MOV BH, 0
MOV AL, USER_INPUT_STRING + 2 + BX - 1
MOV USER_INPUT_STRING + 2, AL
MOV USER_INPUT_STRING + 2 + BX - 1, AH
RET
swap ENDP
END main
All programs change the content of the string. To undo this, you have to call swap
a second time. It is up to you to incorporate the second part.