Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вычисление целочисленного выражения, ASM – на уровне освоения 
V
    Опции темы
Y999igor
Дата 21.8.2006, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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

PM MAIL   Вверх
denks
Дата 21.8.2006, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 16.4.2006

Репутация: нет
Всего: нет



Я сам в асме новичок, но может тебе чем-нибудь поможет этот код. Проверил - работает для конкретных значений. ты уж сам вставь туда функцию ввода числа с клавиатуры.

Код

.386
.model flat,stdcall
option casemap:none
include C:\masm32\include\user32.inc
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
.data
a dd 16
cc dd 3
d dd 2
e dd ?
f dd ?
z dd 4
dwResult dd 0 ; результат действия
szText db 2 dup(0)   ;0,0, - на 1 больше чем кол-во символов в результирующем числе
zcaption db "результат",0
szFormat db '%d',0 ; %d - для типа integer
.code
start :
mov eax,cc
imul eax,2
sub eax,d
add eax,23
mov e,eax ;первая скобка
mov eax,a
xor edx,edx
div z
sub eax,1
mov f,eax ; вторая скобка
mov eax,e
xor edx,edx
div f
mov dwResult,eax
invoke wsprintf, ADDR szText, ADDR szFormat, dwResult ; позволяет произвести форматированную запись в буфер последовательности символов и значений аргументов
invoke MessageBox, 0, ADDR szText, addr zcaption, MB_OK
invoke ExitProcess, 0
end start

PM MAIL   Вверх
Y999igor
Дата 22.8.2006, 05:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 20.8.2006

Репутация: нет
Всего: нет



Спасибо denks. Буду разбираться. Я пока в небольшом замешательстве по поводу структур и методов построения исходников. Дело в том, что в книжках читал про одно, а в кодах на форуме вдруг замечаю нестыковки с моими понятиями. Эх, учиться, учится и учиться!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.0447 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.