Вводить целые числа пока не встретится 0. Определить максимальное введенное число - Assembler

Узнай цену своей работы

Формулировка задачи:

Всем привет! Пытаюсь разобраться в изучении Ассемблера. Поставлена задача: "Вводить целые числа пока не встретится 0. Определить максимальное введенное число". Поскольку заниматься этим начал лишь пару дней назад (и научился писать лишь простенькие примеры), то возникает трудность с реализацией программы. Насколько я понимаю, необходимо использовать цикл, причем цикл LOOPZ/LOOPE. Но я никак не могу понять, как именно построить этот цикл в коде. Помогите, пожалуйста, если вам не тяжело.

Решение задачи: «Вводить целые числа пока не встретится 0. Определить максимальное введенное число»

textual
Листинг программы
.model small
.686
.stack
.data
ten dd  0Ah
info    db  "Вычисление максимального числа из множества введенных чисел. $"
smsa    db  0Dh, 0Ah,"Вводите числа. Для окончания ввода введите 0 (ноль): $"
smsb    db  0Dh, 0Ah,"Максимальное число среди введенных: $" 
.code
start:  mov ax, @data
    mov ds, ax
    xor esi, esi
    mov dx, offset info
    mov ah, 9h
    int 21h
again:  mov dx, offset smsa
    mov ah, 9h
    int 21h
    mov ecx,11      ; желаемое кол-во цифр
    call    _cgetl
    jc  quit        
    or  eax, eax
    jz  exit
    cmp esi, eax
    cmovs   esi, eax
    jmp again
exit:
    mov dx, offset smsb
    mov ah, 9h
    int 21h
    mov eax, esi
    call    _cputl
    call    crlf
quit:   mov ax, 4c00h
    int 21h
 
; eax - signed long
_cputl:
;;;        push ebx
    mov ebx, eax
    neg ebx
    cmovs   ebx, eax
    js  @F
    mov al, '-'
    int 29h
@@: mov eax, ebx
;;; pop ebx
 
; eax - unsigned long
 
_cputul:
;;; pushad
    xor ecx, ecx
    mov ebx, 0Ah
    xor esi, esi
    xor edi, edi
@@: xor edx, edx
    inc ecx
    idiv    ebx
    shld    edi, esi, 4
    shl esi, 4
    or  si, dx
    test    eax, eax
    jnz @B
    mov edx, esi
@@: mov al, dl
    and al, 0fh
    or  al, 30h
    shrd    edx, edi, 4
    shr edi, 4
    int 29h
    loop    @B
;;; popad
    ret
 
 
; console - get signed long
; ввод с консоли целого знакового с отработкой удаления символа
; на входе: CX - кол-во цифр
; на выходе: EAX - введённое число или -1, если нажат <ESC>, а также CY=1
_cgetl:     pushad
        xor edx, edx
        mov ebp, edx
        mov ebx, ecx
@l:
        call    getch
        or  al,al
        jz  @l
        cmp al, 1Bh     ; <ESC>?
        jz  cancel
        cmp al, 0Dh         ; <Enter>?
        jz  done
        cmp al, '-'
        jz  sign
        cmp al, 08h         ; <BkSp>?
        jnz @F
        call    rubout
        jmp @l
@@:     cmp al, 30h
        jb  @l
        cmp al, 39h
        ja  @l
        movzx   eax,al          ; убираем из eax лишнее
            lea edx,[edx*4+edx]     ; EDX = EDX * 5
            lea edx,[edx*2+eax-48]  ; EDX = EDX * 2 + символ из AL - '0'
            int 29h
            loop    @l
; выход
done:       mov eax, edx        ;
        or  ebp, ebp
        jz  @F
        neg eax
@@:     clc
        jmp ex
; отмена, взводим Carry(CY), EAX = -1
cancel:     xor eax, eax
        dec eax             ; EAX = -1
        stc       
ex:     mov ss:[esp+1Ch], eax
        popad
        ret              ;
sign:       cmp ebx, ecx    ; первый символ?
        ja  @l              ; нет
        inc ebp
            
        int 29h
        jmp @l      
; ввод символа
getch:      xor     ax, ax
        int 16h
        ret
; новая строка
crlf:       push    ax
        mov ax, 0A0Dh
        int 29h
        xchg    al,ah
        int 29h
        pop ax
        ret
; отработка <BkSp>
rubout:     cmp ebx, ecx    ; первый символ?
        ja  @r              ; нет
        test    ebp,ebp     ; минус вводили?
        jz  @e              ; нет
        dec ebp             ; убираем флаг
        jmp @bs             ; стираем "-" с экрана
@r:     mov eax, edx
        xor edx, edx
        idiv    dword ptr ten   ; делим наше вводимое число на 10.
        mov edx,eax
        inc ecx
@bs:        call    bksp
@e:     ret
; курсор взад на 1 позицию
bksp:       mov ax, 2008h
        int 29h
        xchg    ah,al
        int 29h
        xchg    ah,al
        int 29h
        ret
        end start

Объяснение кода листинга программы

  1. Переменная ten содержит число 10.
  2. Переменная info содержит строку Вычисление максимального числа из множества введенных чисел. $.
  3. Переменная smsa содержит строку Вводите числа. Для окончания ввода введите 0 (ноль): $.
  4. Переменная smsb содержит строку Максимальное число среди введенных: $.
  5. Переменная ecx используется для задания желаемого количества цифр для ввода. Значение по умолчанию - 11.
  6. Переменная eax используется для хранения введенного числа.
  7. Переменная esi используется для хранения максимального введенного числа.
  8. Переменная edx используется для хранения результата деления введенного числа на 10.
  9. Переменная ebx используется для хранения текущего вводимого числа.
  10. Переменная ebp используется для хранения флага, указывающего, был ли введен минус.
  11. Переменная edi используется для хранения индекса строки, которую нужно вывести на экран.
  12. Переменная al используется для хранения текущего вводимого символа.
  13. Переменная ah используется для хранения текущего значения регистра AH.
  14. Переменная cx используется для хранения текущего значения регистра CX.
  15. Переменная ds используется для хранения текущего значения регистра DS.
  16. Переменная es используется для хранения текущего значения регистра ES.
  17. Переменная ss используется для хранения текущего значения регистра SS.
  18. Переменная sp используется для хранения текущего значения регистра SP.
  19. Переменная bp используется для хранения текущего значения регистра BP.
  20. Переменная di используется для хранения текущего значения регистра DI.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4 из 5
Похожие ответы