2013-04-06 7 views
0

У меня есть простая программа сборки, где я хочу разделить два числа (два байта) и распечатать остаток. Вот мой кодDivide overflow в языке ассемблера

.model small 
.stack 256 

.data 
    ten dw 10 

.code 
main proc 
    mov ax, @data 
    mov ds, ax 

    mov ax, 12 ; divident 
    div ten ; ax/10 

    mov ah, 9 ; for printing dx 
    int 21h 

    mov ax, 4c00h ; ending program 
    int 21h 
main endp 
end main 

Так что, когда я запускаю этот код результат является «переполнение Divide», и я понятия не имею, почему происходит переполнение. Любые идеи?

+1

Вы пытались найти сборку проблемы разделения/вопросы? Ваш вопрос не первый. Это дубликат других. –

ответ

1

DIV mem16 делит DX:AX на данный операнд. Поэтому вам нужно подписать-удлинить AX в DX, который вы легко можете сделать с инструкцией CWD перед делением (в вашем случае MOV DX,0 или XOR DX,DX также будет работать). Т.е .:

mov ax,12 
cwd 
div ten 

Еще одна проблема с вашим кодом является то, что вы, кажется, предположить, что int 21h/ah=9 может быть использована для печати числовых значений. Это не относится к делу. Если вы хотите напечатать значение DX (т. Е. Остаток), вам придется сначала преобразовать его в строку и напечатать эту строку. В противном случае вы просто получите вывод мусора, и ваша программа может даже сбой.

+0

Интересно то, что когда я отлаживаю свой код, все правильно, но когда он пытается распечатать значение, он печатает мусор в режиме отладки и «Divide overflow» в обычном режиме – nabroyan

+0

Отладчик очищает DX для вас. – gukoff

+0

В некоторых средах вы можете закончите с «DX» 0, когда начнется ваша программа. В этих случаях деление будет работать правильно, но вы не должны полагаться на это. Используйте 'CWD', и вы будете в безопасности. Что касается печати мусора, я упомянул, почему это происходит во второй части моего ответа. Если вы хотите напечатать только одну цифру, вы можете добавить '' 0'' в 'DL' после деления и использовать' int 21h/ah = 2'. Или вы можете реализовать свою собственную функцию int-to-string, см., Например, [мой ответ на этот более ранний вопрос] (http://stackoverflow.com/questions/15204659/how-to-print-a-number-in-assembly-8086?rq=1). – Michael

0

Напишите «десять DB 10» или «div BYTE PTR ten».

И я уверен, что если вы пишете что-то вроде

mov cl, 10 
div cl 

вы также получите то, что вы хотите. Если это должно быть разделение слов, вы должны очистить DX, Майкл написал в сообщении ниже, как.

BTW Я не знаю, какой сборочный диалект есть, но вам действительно нужно это написать?

mov ax, @data 
mov ds, ax 

Не указывает ли DS на раздел данных с помощью defaut?

И 09h не делает то, что вы хотите. Взгляните на 02h.

+0

'mov segreg, reg16' - отлично действующая инструкция x86. – Michael

+0

Я могу ошибаться, но я думал, что это не работает в DOS. (И действительно работает в dosbox и т. Д.) Я всегда пишу push reg16/pop segreg. – gukoff

+0

Возможно, вы думаете о чем-то вроде 'mov es, 0a000h'. Это не действительная инструкция, и это можно сделать с помощью 'push/pop'. Перемещение 16-битного GPR в регистр сегментов было доступно с самых первых моделей x86. – Michael

0

.MODEL небольшой .stack 256

.data десять Dw 10

.code Основной Proc мов ах, @data MOV DS, AX

mov ax, 12 ; divident 
div ten ; ax/10 
add dl,48; 
mov ah, 02h ; for printing dl not the ascii vlaue 
int 21h 

mov ax, 4c00h ; ending program 
int 21h 

главный ENDP end main

 Смежные вопросы

  • Нет связанных вопросов^_^