EDIT: После того, как комментарий Ped7g, я переработал код , Этот новый не использует стек для изменения строки, и строка не читается как целая строка, но она считывается символом char, пока не нажимается «Enter». Ниже приведен новый код.
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
Старый ответ:
Вы можете попробовать использовать ЛИФО свойство стека. Ниже приведен пример кода, который меняет строку, используя ее. Алгоритм помещает каждый символ из начала входной строки, а затем выплывает к результату (в обратном порядке).
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
в 'swapy:' вы сохраняете последний символ снова и снова. Вы неправильно обрабатываете состояние, показывая символы строки и аналогичные. Поскольку вы используете * Tasm *, у вас также есть * td * (Turbo debugger), который является довольно хорошим отладчиком. –
Что Маргарет сказала, и если вы ожидаете, что кто-то ищет ваши ошибки в коде asm, прокомментируйте это. Это также поможет вам при кодировании сначала сосредоточиться на алгоритме и потоке выполнения, затем распределять регистры и другие ресурсы и, наконец, заполнять инструкции, это проще, чем решать все этапы одновременно в голове или просто выполнять произвольные инструкции до тех пор, пока код работает случайно. Но избегайте комментариев вроде 'cmp al, 31h; сравните al с 31h', это очевидно. Напишите там намерения, которые заставили вас написать этот параграф кода, например '; чтение символов до ввода «1». – Ped7g
Помимо того, что говорили другие, причина, по которой вы получаете ведущий $, заключается в том, что вы добавляете 'di' в' swapy' и пост-декрементируете его в своем цикле 'l4' (это не очень описательное имя btw). Вероятно, вы захотите _pre_-decment 'di' во втором цикле. – Michael