Другие языки программирования и технологии

assembler почему с этой процедурой макс значение ввода =25

Vvod proc
push cx dx
mov cx,0
mov bx,0
Vv2:mov ah,00h
int 16h
mov ah,06h
mov dl,al
int 21h
cmp al,13
je V_end
cmp al,'-'
jne Vv1
mov bh,1; признак отрицательного числа
jmp vv2
Vv1:sub al,30h
add cl,al
mov al,cl
imul k10
mov cl,al
jmp Vv2
V_end:mov ax,cx
idiv k10
cmp bh,1
jne Vv3
neg ax
Vv3:pop dx cx
ret
Vvod endp
почему с этой процедурой ввода числа в 10с/c, максимальное значение ввода равно 25, последующие числа начинаются с нуля (т. е. 26=0, 27=1....)
Потому что, во-первых, вы делаете умножение, если можно так сказать, по модулю 256. То есть для хранения произведения используется регистр размером 1 байт.
Во-вторых, умножение вы делаете сразу за добавлением очередной цифры, а не перед этим. Т. е. умножаете на 10 не тогда, когда это нужно делать, а заранее. А в конце дополнительно производите деление на 10.

Попробую объяснить на примере для числа 26.
Ввод цифр числа и их "накопление" производится по схеме Горнера.
Вы реализовали её так:
((0 + 2) * 10 + 6) * 10 / 10
Так вот, значение выражения ((0 + 2) * 10 + 6) * 10 равно 260, оно не умещается в 8-ми разрядном регистре и усекается до 4.
Затем, когда в конце вы делите 4 на 10, получается целая часть частного, равная нулю.

Схема Горнера реализуется так:
(0 * 10 + 2) * 10 + 6 и окончательное деление не требуется.

Исправленная подпрограмма, позволяющая вводить числа от -32768 до 32767:

;В сегменте данных исправьте
k10 dw 10

Vvod proc
    push cx dx
    mov cx,0
    mov bx,0
Vv2: mov ah,00h
    int 16h
    mov ah,06h
    mov dl,al
    int 21h
    cmp al,13
    je V_end
    cmp al,'-'
    jne Vv1
    mov bh,1; признак отрицательного числа
    jmp vv2
Vv1: sub al,30h
    cbw
    xchg ax,cx
    imul k10
    add cx,ax
    jmp Vv2
V_end: mov ax,cx
;и деление теперь не нужно
    cmp bh,1
    jne Vv3
    neg ax
Vv3: pop dx cx
    ret
    Vvod endp
Лёха .
Лёха .
51 590
Лучший ответ