Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.10.2010, 23:14   #1
Teor
Пользователь
 
Регистрация: 20.12.2008
Сообщений: 46
По умолчанию Переполнение деления и число 2559

Всем привет. Нужна небольшая помощь в такой программе:

Код:
.model small
.stack 100h
.data
ErrMess db 'Число макс. 2559!',0dh,0ah,'$'
NUMBER dw 2558
Ten db 10
.code
PRINTNUM proc
mov cx,0
repeat:
cmp ax,2559
jg ErrExit
div [ten]
mov dx,0
mov dl,al
mov al,ah
add al,'0'
mov ah,0
push ax
mov ax,dx
inc cx
cmp ax,0
je PRINTDIGITS
jmp repeat
PRINTDIGITS:
mov ah,2
pop dx
int 21h
loop PRINTDIGITS
jmp MOUT
ErrExit:
mov ah,9
mov dx, offset ErrMess
int 21h
MOUT:
ret 
PRINTNUM endp
StartProg:
mov ax,@data
mov ds,ax
mov ax,[Number]
Call PRINTNUM
mov ah,8
int 21h
mov ah,4ch
int 21h
end StartProg
Данная программа выводит на экран число Number, которое сейчас равняется 2558. Собственно вопрос в том, почему числа более чем 2559 не выводятся на экран, а именно выскакивает сообщение "Переполнение деления". Как я понял это зависит от числа на которое делим, но что конкретно происходит понять не могу. Может кто-то знает в чем фишка?
Teor вне форума Ответить с цитированием
Старый 10.10.2010, 23:35   #2
Ulex
Непрофессионал
Участник клуба
 
Аватар для Ulex
 
Регистрация: 01.01.2008
Сообщений: 1,405
По умолчанию

Так как делителем является переменная размерностью байт (Ten db 10), то результат от деления размещается в регистре al, а остаток в ah (это 8-ми битные части регистра eax). Ну а так как результат от деления 2560 на 10 составляет 256 и его невозможно разместить в регистре al, то и возникает ошибка "Переполнение деления".
И чем больше я узнавал людей, тем больше мне нравились компьютеры.
------------------------------------
Страничка с моими программками http://ulex-masm.ru
Ulex вне форума Ответить с цитированием
Старый 10.10.2010, 23:37   #3
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

Потому что при делении 16-разрядного числа на 8-разрядное результат помещается в 8-разрядный регистр al. 2600/10=260 уже не вмещается в al, вот и происходит ошибка деления. Выход делить DX:AX на 10 как шестнадцатиразрядное число.
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 10.10.2010, 23:59   #4
Ulex
Непрофессионал
Участник клуба
 
Аватар для Ulex
 
Регистрация: 01.01.2008
Сообщений: 1,405
По умолчанию

Вот оно:

Код:
.model small
.stack 100h
.data
NUMBER dw 65010
Ten dw 10
.code
PRINTNUM proc
mov cx,0
repeat:
xor dx,dx
div [ten]
add dx,'0'
push dx
inc cx
cmp ax,0
je PRINTDIGITS
jmp repeat
PRINTDIGITS:
mov ah,2
pop dx
int 21h
loop PRINTDIGITS
ret 
PRINTNUM endp
StartProg:
mov ax,@data
mov ds,ax
mov ax,[Number]
Call PRINTNUM
mov ah,8
int 21h
mov ah,4ch
int 21h
end StartProg
И чем больше я узнавал людей, тем больше мне нравились компьютеры.
------------------------------------
Страничка с моими программками http://ulex-masm.ru
Ulex вне форума Ответить с цитированием
Старый 11.10.2010, 05:07   #5
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Teor
данная программа позволит делить числа от 65535 до 0 на 10 -- здесь деление заменено на умножение, а результат всегда в регистре DX
Код:
; masm dos exe #
.286
.model small
.data
X dw 0FFFFh
result dw ?
.code
start:	mov ax,@data
	mov ds,ax
	mov ax,52429; "волшебное число"
	mul X
	shr dx,3
	mov result,dx; result:= X/10     
	mov ah,4Ch
	int 21h
end start
а эта программа переводит шестнадцатеричное значение в result для вывода на экран
Код:
; masm dos exe #
.286
.model small
.code
start:	mov ax,@data
	mov ds,ax
	mov es,ax
	mov ax,3
	int 10h; чистим экран
	mov si,offset result
        mov di,si
	mov bx,len/2;длина результата в словах
@@:	lodsb
	xchg al,byte ptr result[bx+1]
	stosb
	dec bx
	jnz @b
; перевожу hex->dec
	mov si,offset terminator-1;
@3:	mov cx,len;длина в байтах значения делимого
	mov di,offset result
	xor ax,ax
@@:	mov al,[di];делимое
	div ten
	stosb
	loop @b
	or [si],ah;остаток
	dec si
	cmp word ptr [di-2],0
	jne @3
	cmp word ptr [di-4],0
	jne @3
; вывожу на экран
	inc si
	mov dx,si
	mov ah,9
	int 21h
	mov ah,0
	int 16h
	mov ah,4Ch
	int 21h;выходим из программы
.data
result	dd 0FFFFFFFFh
len = $-result
ten db 10
buffer db 14 dup ('0')
terminator db '$'
end start

Последний раз редактировалось Mikl___; 12.10.2010 в 03:47.
Mikl___ вне форума Ответить с цитированием
Старый 11.10.2010, 21:53   #6
Teor
Пользователь
 
Регистрация: 20.12.2008
Сообщений: 46
По умолчанию

Всем спасибо за ответы. Вы помогли мне даже больше, чем нужно было
Teor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переполнение деления!!! zero-cool Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 5 28.09.2010 21:10
Игра,угадай задуманное число,Ошибка деления на ноль!!! Rid Помощь студентам 4 22.10.2009 21:12
Как узнать что число не Float(без остатка) при результате деления? zotox Помощь студентам 7 19.07.2009 15:49
Переполнение стека Ake Паскаль, Turbo Pascal, PascalABC.NET 3 30.05.2009 22:39
Переполнение Стека Викдон Паскаль, Turbo Pascal, PascalABC.NET 0 19.12.2008 19:16