Ввести два 16-битовых целых числа А и В. Вычислить результат логического побитового исключающего ИЛИ чисел 10* - Assembler

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

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

Помогите найти ошибку. Все компилируется, но при запуске вылетает с ошибкой.
model small
outmsg macro msg ; macros dlya vivoda na ekran
    push eax
    push edx
    mov ah,09h
    lea dx,msg
    int 21h
    pop edx
    pop eax
endm
 
.stack 100h ;zadaem razmer steka
 
.data ;nachalo bloka peremennih
    MSG1 DB "Input A(0..255): ",'$'; zadaem strokovie peremennie
    MSG2 DB "Input B(0..255): ",'$'
    ERROR_MSG DB "Slishkom bolshoe chislo!",'$'
.code ;nachalo bloka koda
.486 
 
calc proc far ;procedura operacii 
    ;vipolnyaem 6*B^2
    mov ecx,eax
    mov eax,ebx
    mul ebx
    mov ebx,eax
    mov eax,6
    mul ebx
    mov ebx,eax
    ; vipolnyaem A*10
    mov eax,10
    mul ecx
    xchg eax,ecx
    ;vipolnyaem pobitovoe logicheskoe ili resultat zanositsya v eax
    xor eax,ebx
calc endp
 
printRes proc    
    test eax,eax 
    jns nsig 
    mov ecx,eax 
    mov ah,02h
    mov dl,'-'
    int 21h
    mov eax,ecx 
    neg eax 
nsig:  
    xor ecx,ecx
    mov ebx,10 
nums:
    xor edx,edx 
    div ebx 
    push edx 
    inc cx 
    test eax,eax 
    jnz nums
    mov ah,02h 
show:
    pop edx 
    add dl,'0' 
    int 21h 
    loop show 
    ret
printRes endp

MAIN: ;tochka vhoda v programmu
    mov ax,@data ;zadaem adress segmenta dannih
    mov ds,ax
    xor eax,eax ; eax = 0
    xor ebx,ebx ; ebx = 0
    xor ecx,ecx ; ecx = 0
    mov edx,10 ; stepen sistemi ischisleniya 
    outmsg MSG1 ; Daem zapros na A
    
INPUT_A:
    mov ch,01h;vvod s klaviaturi
    int 21h  ;prerivanie
    je NEXT ;perehod k B
    sub cl,30h ;perevodim simvol v chislo
    cbw ;rasshiryaem do word
    mul edx ;primenyaem systemy ischisleniya
    add eax,ecx ;dobavlyaem vvedennuyu cifru k predidushemy chislu
    jmp INPUT_A ;povtoryaem cikl
    
NEXT:
    outmsg MSG2 ; Daem zapros na B
    
INPUT_B:
    mov ch,01h;vvod s klaviaturi
    int 21h  ;prerivanie
    je END_INPUT ;okonchanie vvoda
    sub cl,30h ;perevodim simvol v chislo
    cbw ;rasshiryaem do word
    mul edx ;primenyaem systemy ischisleniya
    add ebx,ecx ;dobavleyaem vvedennuyu cifru k predidushemy chislu
    jmp INPUT_B ;povtoryaem cikl    
 
END_INPUT:
 
    cmp eax,255 ;proverka na dopustimost znacheniya
    ja ERROR
    cmp ebx,255 ;proverka na dopustimost znacheniya
    ja ERROR
    
    call calc
 
ERROR:
    outmsg ERROR_MSG
    jmp EXIT    
 
EXIT:
    mov ax,4c00h
    int 21h    
end MAIN
Заранее спасибо)

Решение задачи: «Ввести два 16-битовых целых числа А и В. Вычислить результат логического побитового исключающего ИЛИ чисел 10*»

textual
Листинг программы
.model small                ;model pamati small
outmsg macro msg
    push eax
    push edx
    mov ah,09h
    lea dx,msg
    int 21h
    pop edx
    pop eax
endm
.stack 256              ;stek zanimaet 256 baitov
.data                   ;segment dannyh
    Mess1     db 'Vvedite chislo A (-224..+225): $'
    Mess2     db 'Vvedite chislo B (-224..+225): $'
    Exit_Mess db 10,13,'Nazhmite lubuju klavishu...$'
    error db "incorrect number$"
    buff    db 6,7 Dup(?)
.code  
.486             
    ;procedura vychislaet 6*B^2  i A*10
    ; Znachenie B peredaetsa cherez registr bx
    ; Znachenie A peredaetsa cherez registr bp
;Rezultat vychislenij peredaetsa cherez registr ax.
calc proc far
    mov ax,bx; zanosim B v ax
    mul bx ;umnojaem B na B
    mov bx,ax ;vozvrashaem resultat v bx
    mov ax,6 ;zanosim 6 v ax
    mul bx ;umnojaem B^2 na 6
    mov bx,ax ;vozvrashaem resultat 6*B^2
   ;vipolnyaem A*10
    mov ax,10 ;zanosim v ax 10
    mul bp ;umnojaem A na 10
    mov bp,ax ;vozvrashaem resultat  
    xor bp,bx  ;vipolnyaem pobitovoe logicheskoe ili resultat zanositsya v bp
    mov ax,bp ; otpravlyaem resultat v ax
    ret
calc endp
 
;procedura vyvodit chislo iz registra ax na ekran
prints proc  ;pechataet soderjimoe ax
      mov cx,10         ;v cx zanosim delitel 10
    xor di,di           ;ochistka di (kolichestvo cifr v chisle)
    ;esli ax<0, to pechataem '-' i delaem ax polozhitelnym 
    or ax,ax            ;proveraem ax
    jns conv            ;esli ax>0 (SF=0), to perehod na metku conv
    push ax             ;pomeschaem ax v stek
    mov dx,'-'          ;zanosim v dx '-'
    mov ah,2                ;vyvod '-' na ekran
    int 21h
    pop ax              ;vosstanavlivaem ax
    neg ax              ;delaem ax polozhitelnym
 conv:
    xor dx,dx           ;ochistka dx
    div cx                      ;dl = ax mod 10, 
    add dl,'0'          ;perevodim ostatok v simvol
    inc di              ;uvelichivaem kolichestvo cifr v chisle na 1
    push dx                     ;ostatok pomeschaem v stek
    or ax,ax            ;proveraem ax (chastnoe)
    jnz conv            ;esli ax<>0, to perehod na metku conv
                    ;i povtoraem delenie
    ;vyvod cifr iz steka na ekran
print:
    pop dx              ;izvlekaem iz steka ocherednoj simvol
    mov ah,2            ;vyvodim ego na ekran
    int 21h
    dec di              ;umenshaem schetchik cifr
    jnz print           ;esli di<>0 (ZF=0), to perehod na metku print
                    ;i povtoraem pechat' simvola
    ret             ;vyhod iz procedury          
    prints endp
    
InputInt proc 
INPUT: ; vvod chisla  s klaviaturi
mov ah,0ah
    xor di,di
    mov dx,offset buff ; adres bufera
    int 21h ; prinimaem stroku
    mov dl,0ah
    mov ah,02
    int 21h ; vivodim perevodya stroku
    
    ; obrabativaem bufer
    mov si,offset buff+2 ; berem adres nacala stroki
    cmp byte ptr [si],"-" ; esli perviy simvol -
    jnz ii1
    mov di,1  ; ustanavlivaem flag
    inc si    ; i propuskaem
ii1:
    xor ax,ax
    mov bx,10  ; osnovanie
ii2:
    mov cl,[si] ; berem simvol is bufera
    cmp cl,0dh  ; provaryaem ne posledniy li on
    jz endin
    
    ; esli ne posledniy ti proveryaem na pravilnost
    cmp cl,'0'  ; esli vvedenniy simvol <0
    jb er
    cmp cl,'9'  ; esli vvedenniy simvol >9
    ja er
 
    sub cl,'0' ; perevodim v chislo
    mul bx     ; umnojaem na 10
    add ax,cx  ; dobavlyaem k ostalnim
    inc si     ; ukazatel na sleduyushiy simvol
    jmp ii2     ; povtoryaem
 
    er:   ; esli bila oshibka to soobshaem i vihodim
    mov dx, offset error
    mov ah,09
    int 21h
    int 20h
 
    ; vse simvoli obrabotani chislo nahoditsya v ax
endin:
    cmp di,1 ; esli ustanovlen flag to
    jnz ii3
    neg ax   ; delaem chislo otricatelnim
ii3:
    ret
InputInt endp
main:                   ;tochka vhoda v programmu
    mov ax,@data        ;zanesenie adresa segmenta dannyh v ax
    mov ds,ax           ;kopiruem ax v ds   
    mov dx,10
    outmsg Mess1
    call InputInt
    mov bp,ax 
    outmsg Mess2
    call InputInt
    xor bx,bx
    mov bx,ax    
    call calc
    call prints
    jmp exit
exit:
    lea dx,Exit_Mess        ;v dx zanosim smeschenie Exit_Mess
    mov ah,09h          ;v ah zanosim 9 funkciju DOS    
    int 21h             ;vyzov preryvanija 21h
    ;ozhidanie nazhatija klavishi
    mov ah,00h          ;v ah zanosim funkciju 00h  
    int 16h             ;vyzov preryvanija 16h
    ;vyhod iz programmy  
    mov ah,4ch          ;v ah zanosim funkciju 4Ch DOS  
    int 21h             ;vyzov preryvanija 21h     
 
end main                ;konec programmy main

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

  1. На строке 5 объявляется модель памяти small.
  2. На строках 7-12 объявляются макросы outmsg, который выводит сообщение на экран, соответствующие строки Mess1, Mess2 и Exit_Mess.
  3. На строке 14 объявляется стек размером 256 байт.
  4. На строке 16 объявляется сегмент данных.
  5. На строках 18-25 объявляется переменная error со значением incorrect number.
  6. На строке 26 объявляется переменная buff как массив из 6 элементов.
  7. На строке 31 начинается процедура calc, которая вычисляет результат логического побитового исключающего ИЛИ.
    • Значение переменной B передается через регистр bx.
    • Значение переменной A передается через регистр bp.
    • Результат вычислений сохраняется в регистре ax.
  8. На строке 61 начинается процедура prints, которая выводит число из регистра ax на экран.
  9. На строке 107 начинается процедура InputInt, которая считывает число с клавиатуры.
  10. На строке 171 начинается основная программа main:
    • Сначала вводится число A с помощью вызова процедуры InputInt и сохраняется в регистре bp.
    • Затем вводится число B с помощью вызова процедуры InputInt и сохраняется в регистре bx.
    • Затем вызывается процедура calc для вычисления результата логического побитового исключающего ИЛИ и результат сохраняется в регистре ax.
    • Затем вызывается процедура prints для вывода результата на экран.
    • Наконец, программа завершается с выводом сообщения Nazhmite lubuju klavishu... и ожиданием нажатия клавиши.
  11. Программа завершается с вызовом прерывания 4Ch для выхода из программы.

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

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