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