Сборка сохранения и сравнения символов

Я новичок в сборке, и я пытаюсь сделать следующее:

псевдокод:

 loop:
      input
      if(input == $)
        end loop
      else if(input < savedInput)
        savedInput = input
    ;
    print savedInput

в основном это постоянный цикл, который обнаруживает пользовательские вводы и сравнивает значение ASCII сохраненного ввода с новым вводом, если новый ввод ниже, то он заменяет сохраненный ввод. Если ввод равен $, то цикл завершается и печатается сохраненный ввод.

Это мой код

.MODEL SMALL
.STACK 100h
.DATA
    insertMsg DB 13, 10, 'Introduce un dato: ', 13, 10, '$'

.CODE
    main:
        mov ax,@data
        mov ds,ax                   ; Set DS to point to the data segment
        mov dx,OFFSET insertMsg     ; Point to the insertMsg
    back:
        mov ah,9                    ; DOS: print string: Service 21h, 09h
        int 21h                     ; Display inputMsg
        mov ah,1                    ; DOS: get character: Service 21h, 01h
        int 21h                     ; Get a single-character response
        cmp al,'$'                  ; if character equals $
        je display                  ; goto display
        loop back                   ; loop back

    display:
        mov ah,9            ;DOS: print string: Service 21h, 09h
        int 21h             ;display input
        mov ah,4Ch          ;DOS: terminate program: Service 21h, 4Ch
        mov al,0            ;return code will be 0
        int 21h             ;terminate the program
    end main

Проблема в том, что я не знаю, как сохранять и сравнивать значения ASCII


person I'm not human    schedule 29.10.2017    source источник
comment
Вы уже делаете сравнение. Чтобы сохранить значение, просто выберите регистр, который не уничтожается.   -  person Jester    schedule 29.10.2017
comment
loop back не является хорошим выбором в этом случае, вы хотите сделать jmp back, чтобы всегда прыгать туда, loop не будет прыгать после того, как cx станет равным нулю (и вы не определяете cx, поэтому вы зависите от среды запуска). И loop почти никогда не бывает хорошим выбором, если только вы не играете в гольф на размер кода, пара из инструкций: dec cx jnz label лучше для производительности на современных x86 CPU.   -  person Ped7g    schedule 29.10.2017
comment
Или, в данном случае, jne back вместо условного перехода вперед через безусловную ветвь цикла.   -  person Peter Cordes    schedule 30.10.2017


Ответы (1)


Я добавил некоторые инструкции кода для решения вашей проблемы; Я успешно их протестировал. Существует также новая процедура, отображающая код ASCII. Обратите внимание, что некоторые компиляторы ASM используют DISPLAY как зарезервированное слово (я переименовал его в dispOut):

.MODEL SMALL
.STACK 100h
.DATA
    insertMsg DB 13, 10, 'Introduce un dato: ', 13, 10, '$'
    outputMsg DB 13, 10, 'Dato minore tra quelli inseriti: ', 13, 10, '$'
     ASCIIstr DB 13, 10, 'ASCII= ', 0, 0, 0, 13, 10, '$'

.CODE
main:
    mov  ax,@data           ; ... Set DS
    mov  ds,ax              ; ... to point to the data segment
    mov  dx,OFFSET insertMsg; Point to the insertMsg
    mov  bx,OFFSET ASCIIstr ; Point to the ASCIIstr
    mov  cl,255             ; Set SAVED-INPUT to max-ASCII

back:
    mov  ah,9               ; DOS: print string: Service 21h, 09h
    int  21h                ; Display inputMsg
    mov  ah,1               ; DOS: get character: Service 21h, 01h
    int  21h                ; Get a single-character response
    cmp  al,'$'             ; If character equals $ ...
    je   dispOut            ; ... goto dispOut
    cmp  al,cl              ; If char. read >= SAVED-INPUT ...
    jae  cont               ; ... skip next instruction, else ...
    mov  cl,al              ; ... save char. read (it is < SAVED-INPUT)

cont:
    call dispCode           ; Display ASCII code
    jmp  back               ; Loop back

dispOut:
    mov  dx,OFFSET outputMsg; Point to the outputMsg
    mov  ah,9               ; DOS: print string: Service 21h, 09h
    int  21h                ; Display outputMsg
    mov  dl,cl              ; Load SAVED-INPUT into DL's reg.
    mov  ah,2               ; DOS: display output: Service 21h, 02h
    int  21h                ; Write a single-character
    call dispCode           ; Display ASCII code
    mov  ah,4Ch             ; DOS: terminate program: Service 21h, 4Ch
    mov  al,0               ; Return code will be 0
    int  21h                ; Terminate the program

dispCode:                   ; Display an ASCII code
    ; AL: ASCII code
    ; BX: OFFSET ASCIIstr
    mov  ch,10              ; Load 10 into CH's reg.
    xor  ah,ah              ; AX contains the ASCII code
    div  ch                 ; AH contains the last significant digit
    add  ah,'0'             ; Converts AH into ASCII digit
    mov  ds:[bx+11],ah      ; Store the last significant digit in ASCIIstr
    xor  ah,ah              ; AX contains the ASCII code / 10
    div  ch                 ; AH: penult. sign. digit; AL: 1st sign. digit
    add  ah,'0'             ; Converts AH into ASCII digit
    mov  ds:[bx+10],ah      ; Store the penult. sign. digit in ASCIIstr
    add  al,'0'             ; Converts AL into ASCII digit
    mov  ds:[bx+9],al       ; Store the 1st sign. digit in ASCIIstr
    xchg dx,bx              ; Swap msg offset
    mov  ah,9               ; DOS: print string: Service 21h, 09h
    int  21h                ; Display inputMsg
    xchg dx,bx              ; Swap msg offset
    ret                     ; Return

end main
person Paolo Fassin    schedule 29.10.2017