问题
The string is read until 1 is pressed, and the 1 will be on the last position of the string. I don't know why my output is off, for example the input is: asd1 and the output is: $1111. Anyway, here is my code
data segment
msg db 0dh,0ah,"Your string: $"
rev db 0dh,0ah,"Reverted: $"
s1 db 20 dup('$')
s2 db 20 dup('$')
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
lea dx,msg
mov ah,09h
int 21h
lea si,s1
lea di,s2
mov bx,0
l1: mov ah,01h
int 21h
mov [si],al
inc bx
inc si
cmp al,31h
jnz l1
mov cx,bx
mov di,bx
dec1: dec si
loop dec1
mov cx,bx
l2: mov al,[si]
mov [di],al
dec di
inc si
loop l2
lea dx,rev
mov ah,09h
int 21h
mov cx,bx
l3: mov ah,02h
mov dl,[di]
int 21h
inc di
loop l3
mov ah,4ch
int 21h
code ends
end start
Edit:This is what my code looks now and if I input asd1, then I get 1dserted
回答1:
EDIT: After Ped7g's comment, I reworked the code. This new one doesn't use the stack to reverse the string and the string is not read as a whole string, but it is read char by char until "Enter" is pressed. Below is the new code.
assume cs:code, ds:data
data segment
message db 0Dh, 0Ah, "String: $"
reverse db 0Dh, 0Ah, "Result: $"
string db 255 dup(0)
result db 255 dup('$')
data ends
code segment
start:
mov ax, data
mov ds, ax
; Print "String: "
mov ah, 09h
lea dx, message
int 21h
; Set SI where we read the string
lea si, string
read:
; Read a single character from the keyboard
mov ah, 01h
int 21h
; Save it in the memory
mov [si], al
inc si
; Check if Enter is pressed (if not, then repeat reading)
cmp al, 0Dh
jnz read
; Calculate the length of the string read
mov ax, si
lea bx, string
sub ax, bx
; Set DI at the last char of result
lea di, result
add di, ax
; Decrement one byte to position DI on the last char
; of the string (the Carriage Return)
dec di
; Decrement one byte because we don't want to consider
; the Carriage Return as a part of our reversed string
dec di
; Set SI at the first char of string
lea si, string
reverse_string:
; Copy from the beginning of the initial string
; to the end of the reversed string
mov al, [si]
mov [di], al
; Step
inc si
dec di
; Verify if we have reached the end of the initial string
; (if the "current" char is Carriage Return)
cmp byte ptr [si], 0Dh
jnz reverse_string
; Print "Result: "
mov ah, 09h
lea dx, reverse
int 21h
write:
; Write the whole reversed string on standard output
mov ah, 09h
lea dx, result
int 21h
mov ah, 4Ch
int 21h
code ends
end start
Old answer:
You can try to use the LIFO property of stack. Below is an example of code that reverses a string using it. The algorithm puts every character from the beginning of the input string, and then pops out to the result (in the reverse order).
assume cs:code, ds:data
data segment
msg db 0Dh, 0Ah, "String: $"
rev db 0Dh, 0Ah, "Result: $"
buffer label byte
str_maxlen db 255
str_length db 0
str_string db 255 dup(0)
result db 255 dup('$')
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ah, 09h
lea dx, msg
int 21h ; print "Your string"
mov ah, 0Ah
lea dx, buffer
int 21h ; read your string
cmp str_length, 0
je skip ; check if the input is null
mov ch, 0
mov cl, str_length
lea si, str_string
put_on_stack:
push [si] ; copy on the stack (from string)
inc si
loop put_on_stack
mov ch, 0
mov cl, str_length
lea di, result
get_from_stack:
pop [di] ; copy back to memory (in result)
inc di
loop get_from_stack
mov byte ptr [di], '$'
skip:
mov ah, 09h
lea dx, rev
int 21h ; print "Result: "
mov ah, 09h
lea dx, result
int 21h ; print the result
mov ah,4Ch
int 21h
code ends
end start
来源:https://stackoverflow.com/questions/38824670/assembly-reverse-a-string