2016-08-08 6 views
-2

Строка считывается до тех пор, пока не будет нажата 1, а 1 будет в последней позиции строки. Я не знаю, почему мой выход отключен, например, вход: asd1, а выход: 1111 долларов. Во всяком случае, вот мой кодassembly reverse a string

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: Это то, что мой код выглядит сейчас, и если я вход ASD1, то я получаю 1dserted

+3

в 'swapy:' вы сохраняете последний символ снова и снова. Вы неправильно обрабатываете состояние, показывая символы строки и аналогичные. Поскольку вы используете * Tasm *, у вас также есть * td * (Turbo debugger), который является довольно хорошим отладчиком. –

+1

Что Маргарет сказала, и если вы ожидаете, что кто-то ищет ваши ошибки в коде asm, прокомментируйте это. Это также поможет вам при кодировании сначала сосредоточиться на алгоритме и потоке выполнения, затем распределять регистры и другие ресурсы и, наконец, заполнять инструкции, это проще, чем решать все этапы одновременно в голове или просто выполнять произвольные инструкции до тех пор, пока код работает случайно. Но избегайте комментариев вроде 'cmp al, 31h; сравните al с 31h', это очевидно. Напишите там намерения, которые заставили вас написать этот параграф кода, например '; чтение символов до ввода «1». – Ped7g

+0

Помимо того, что говорили другие, причина, по которой вы получаете ведущий $, заключается в том, что вы добавляете 'di' в' swapy' и пост-декрементируете его в своем цикле 'l4' (это не очень описательное имя btw). Вероятно, вы захотите _pre_-decment 'di' во втором цикле. – Michael

ответ

3

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 
+3

Я бы чувствовал меньше «omg», если бы вы отметили, что это упражнение push/pop (stack) (и на самом деле очень неэффективный способ, как это сделать). Или, если вы будете читать ввод на каждый символ, как это делает OP, и сразу же нажимайте каждый символ, тогда для этого потребуется немного больше смысла использовать стек. BTW, push/pop будет использовать как минимум 16b или 32b фрагмент данных, поэтому вы удваиваете или увеличиваете ширину общей ширины байтов в четыре раза, и просмотр содержимого стека во время этого обратного хода может быть весьма интересным для новичков asm :). – Ped7g