alexandrknyazev13071995
@alexandrknyazev13071995

Не работает деление в ассемблере. Что я сделал не так?

Пытаюсь разделить сначала первые два элемента массива arr16 на первый элемент массива arr8, затем третий и четвертый элемент arr16 на первый элемент массива arr8, первое деление проходит хорошо, но при добавлении второго деления в код - он компилируется, но экзешник не запускается и ничего не выводит:
.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include <\masm32\include\debug.inc>
includelib <\masm32\lib\debug.lib>

.data

num1 dd ?
ost1 dd ?
num2 dd ?
ost2 dd ?
num3 dd ?
num4 dd ? 
arr16 dd 0000b, 0001b, 0010b, 0100b ;массив - делимое 16 байт
arr8 dd 0001b, 0001b ; массив - делитель 8 байт
; Деление:
;   в роли делимого выступает пара регистров EDX:EAX - если делитель имеет размерность двойное слово (4 байта), 
;   тогда после деления частное находим в регистре EAX, 
;   остаток от деления - в регистре EDX.
.code
start:
mov edx, [arr16]    ; заносим в edx первый элемент массива
mov eax, [arr16+4]  ; заносим в eax второй элемент массива
div [arr8]          ; делим число edx:eax на первый элемент массива с делителем
mov num1,eax        ; после деления записываем в num1 частное
mov ost1, edx       ;  а в ost1 записываем остаток от деления
add [arr16+8], edx  ; добавляем остаток к третьему элементу массива- делимого
xor eax,eax         ; очищаем eax
xor edx,edx         ; очищаем edx
mov edx, [arr16+8]  ; третий элемент
mov eax, [arr16+12] ; чтвертый элемент
div [arr8]
;mov num2, eax
;mov ost2, edx
PrintLine
PrintDec num1
PrintLine
invoke ExitProcess, 0
end start

Что я сделал не так?
  • Вопрос задан
  • 1311 просмотров
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
mov edx, [arr16] ; заносим в edx первый элемент массива
mov eax, [arr16+4] ; заносим в eax второй элемент массива

Начнём с того, что в edx нужно поместить старшую часть делимого, а в eax -- младшую, а на x86 слова в память записываются младшей частью вперёд (little endian).

Если результат деления не помещается в eax вы получите исключение #DE, а при делении числа 0x0000000100000000 (а именно его вы делите, загрузив в eax 0 а в edx 1) на 1 результат определённо в 32 бита не влезет.

Вообще, глядя на ваши вопросы создаётся впечатление, что вы хотите реализовать на ассемблере длинную арифметику. Но длинное деление таким образом, как вы пытаетесь сделать, точно не работает. Вам надо либо побитово делить "в столбик", либо аппроксимировать каким-то рядом (либо ещё как-то, как мне не пришло в голову).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы