![]() |
|
|
![]()
|
|
| Y999igor |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 20.8.2006 Репутация: нет Всего: нет |
Исходник наковырять пытался, но получилось очень длинно и думаю, что неверно. (модули ввода вывода ест-но содрал…) ASM – на уровне освоения, поэтому – помогите кто может. А задачка такая:
(2∙c - d + 23) / (a/4 - 1) Вычислить заданное целочисленное выражение для исходных однобайтных знаковых чисел. Результаты вычисления отобразить на экране монитора. Запуская EXEшник – получаю «Переполнение деления». Заранее благодарен. data segment ;кстати - данные сначала были... data ends code segment ASSUME CS:CODE,DS:CODE kns1 DB 2 ;Объявление байтовых констант kns2 DB 23 kns3 DB 4 c DB ? ;Объявление переменной "с" d DB ? a DB ? x DW ? zxcv PROC NEAR ;метка кода с ближним типом обращения mov AL,kns1 ;Загрузка константы 2 в регистр AL IMUL c ;умножение "2•c ---> AX" MOV DX, AX ;преремещение результата умножения "2•c ---> DX" mov AL,d ;Загрузка переменной d в регистр AL sub DX,AX ;вычитание "d", содержащегося в регистре AX из ;результата умножения "2•c", содержащегося в регистре DX ;результат вычитания возвращается в регистр DX mov AL,kns2 ;Загрузка константы "23" в регистр AL add DX,AX ;сложение содержимого регистров DX и AX т.е. ;(2•c - d) + (23) ;результат сложения возвращается в регистр DX mov AL,a ;Загрузка переменной "a" в регистр DX idiv kns3 ;деление содержимого регистра AX на 4 ;результат деления возвращается в регистр АX dec AX ;вычитание единицы из содержимого регистра АX mov DX,CX ;преремещение результата вычисления "(2•c - d) + (23)" ;из регистра CX в регистр DX xchg AX,DX ;поменялис содержимым регистров idiv DX mov AX,DX ;результат деления возвращается в регистр AX mov x,AX ;Сохранение результата call procoutnum ;вызов процедуры вывода числа на экран zxcv endP ; ** ** ** ** ** В Ы В О Д Н А Э К Р А Н ** ** ** ** ** ; Перевод курсора на новую строку экрана procnl proc near push dx push ax mov ah,2 mov dl,13 ;CR (курсор на начало строки) int 21h mov dl,10 ;LF (курсор на следующую строку) int 21h pop ax pop dx ret procnl endp ;****************************************************************************** ; П Р О Ц Е Д У Р А В Ы В О Д Ц Е Л О Г О Ч И С Л А С О З Н А К О М procoutnum proc near ;точка входа в процедуру. push bp ;загрузка слова в стек mov bp,sp push ax push dx push si sub sp,6 ;отвести 6 байтов в стеке под число ;учет знака cmp dh,1 ;вывод со знаком (dh-1)? jne pon0 cmp ax,0 jge pon0 mov dh,2 ;если вывод со знаком и ах<0, neg ax ;то dh:=2,ax:=abs(ax) pon0: push dx ;спасти dh (знак)и dl (ширину) ;запись цифр числа в стек (в обратном порядке) xor si,si ;si - кол-во цифр в числе pon1: mov dx,0 ;ах -> (dx,ax) div cs:ten ;ax=ax div 10;dx-ax mod 10 add dl,'0' mov [bp-8+si ],dl ;цифра -> стек inc si or ax,ax jnz pon1 ;еще не 0 ;запись минуса,если есть,в стек pop dx cmp dh,2 jne pon2 mov byte ptr [Ьр-8+si],'-' inc si ;печать пробелов впереди pon2:mov dh,0 ;dx - ширина поля вывода mov ah,2 ;функция 02 прерывания 21h pon21:cmp dx,si jle роnЗ ;ширина <= длина числа push dx mov dl,'' int 21h pop dx dec dx jmp pon21 ;печать (минуса и) цифр роnЗ: dec si mov dl,[Ьр-8+si] int 21h or si,si jnz роnЗ ;выход из процедуры add sp,6 pop si pop dx pop ax pop bp ret ten dw 10 procoutnum endp ;****************************************************************************** ; ВВОД С КЛАВИАТУРЫ maxb db 128 ;макс,размер буфера ввода sizeb db 0 ;число введенных символов в буфере buf db 128 dup(?);сам буфер ввода posb db 0 ;номер послед,считан,символа из buf readbuf proc near push ax push dx push ds mov dx,cs mov ds,dx lea dx,buf-2 ;ds:dx -адрес buf [-2] mov ah,0Ah ;ввод строки в буфер (включая Enter) int 21h call procnl ;курсор на новую строку экрана inc cs:sizeb ;в длине учесть Enter mov cs:posb,0 ;сколько символов ухе считано из buf pop ds pop dx pop ax ret readbuf endp ;****************************************************************************** ; Ввод символа (с пропуском или без пропуска Enter) procinch proc near push bx princh1: mov bl,cs:posb ;номер последнего считанного символа inc bl ;след,номер cmp bl,cs:sizeb ;не последний символ буфера? jb princh2 jne princh1O ;буфер не считан до конца? cmp al,0 ;считывать ли конец строки (Enter)? jne princh2 princh1O: call readbuf ;доввод в буфер jmp princh1 ;повторить princh2: mov cs:posb,bl ;запомнить номер считываемого символа mov bh,0 mov al,cs:buf [bx-1] ;al:-символ pop bx ret procinch endp ;*************************************************************** ; П Р О Ц Е Д У Р А В В О Д А Ч И С Л А С К Л А В И А Т У Р Ы procinint proc far push bx push cx push dx ;пропуск пробелов и концов строк вначале prinintl: mov al,0 call procinch ;al -очередной символ (с пропуском Enter) cmp al,'' ;пробел? je prinintl ;проверка на знак mov dx,0 ;dx -вводимое число mov cx,0 ;ch=0-нет цифры,cl=0 -плюс cmp al,'+' je prinint2 cmp al,'-' jne prinint3 mov cl,1 ;cl=l -минус ;цикл по цифрам prinint2: mov al,1 call procinch ;al -очередной символ (Enter -символ) prinint3: ;проверка на цифру cmp al,'9' ja prinint4 ; >'9'? sub al,'0' jb prinint4 ; <'0'? mov ch,1 ;ch=l -есть цифра mov ah,0 mov bx,ax ;bx -цифра как число mov ax,dx ;ах -предыдущее число mul cs:prten ;*10 jc provfl ;>FFFFh (dx<>0) -> переполнение add ax,bx ;+цифра jc provfl mov dx,ax ;спасти число в dx jmp prinint2 ;к след,символу ;кончились цифры (число в dx) prinint4: mov ax,dx cmp ch,1 ;были цифры? jne prnodig cmp cl,1 ;был минус? jne prinint5 cmp ax,8000h ;модуль отриц.числа >8000h ? ja provfl neg ax ;взять с минусом prinint5: pop dx ;выход pop cx pop bx ret prten dw 10 ;++++++++++++++++++++++++++++ ;реакция на ошибки при вводе числа provfl:lea cx,prmsgovfl ;переполнение jmp prerr prnodig:lea cx,prmsgnodig ;нет цифр prerr: push cs ;печать сообщения об ошибке pop ds ;ds=cs lea dx,prmsg mov ah,9 ;outstr int 21h mov dx,cx mov ah,9 ;outstr int 21h call procnl mov ah,4Ch ;finish int 21h prmsg db 'Ошибка при вводе числа:','$' prmsgovfl db 'переполнение','$' prmsgnodig db 'нет цифры','$' procinint endp ;***************************************************** code ends end |
|||
|
||||
| denks |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 16.4.2006 Репутация: нет Всего: нет |
Я сам в асме новичок, но может тебе чем-нибудь поможет этот код. Проверил - работает для конкретных значений. ты уж сам вставь туда функцию ввода числа с клавиатуры.
|
|||
|
||||
| Y999igor |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 20.8.2006 Репутация: нет Всего: нет |
Спасибо denks. Буду разбираться. Я пока в небольшом замешательстве по поводу структур и методов построения исходников. Дело в том, что в книжках читал про одно, а в кодах на форуме вдруг замечаю нестыковки с моими понятиями. Эх, учиться, учится и учиться!
|
|||
|
||||
![]()
|
| Правила форума "Asm для начинающих" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Asm для начинающих | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |