Code (Text): mov ah,9 mov dx,es:[di] Этого категорически недостаточно. Во-первых, в dx попадает содержимое ячейки, куда ссылается 'es:[di]', а не смещение к этой ячейке. Во-вторых, стринг должен быть $-terminated. В общем, код должен выглядеть так: Code (Text): ... num proc ; AX - число ES:DI-куда писать ответ std ; Запись справа налево для STOSB push ax ; Число пока в стек mov al, '$' ; stosb ; Сохраняем признак конца строки pop ax ; Число на место mov bx, 10 ; Делитель Это чтобы добавить '$' в конец. И вызов: Code (Text): push ds push es pop ds mov dx, di mov ah, 9 int 21h pop ds
Mika0x65 : Спасибо, великолепно. Работает. 32 строки понадобилось для того , что бы вывести число на экран) Сразу вспоминается Си со своим printf и %d)))))
И пара десятков килобайт кода для этого Для того и создаются библиотеки процедур, чтобы каждый раз не изобретать велосипед.
опять проблема. Теперь хочу вывести на экран число побольше. Комп выдаёт "переполнение деления", неу то есть значение делимого более чем в 65536 раз больше значения делителя, но на самом деле это вроде бы не так. В чём ошибка? Code (Text): .model small .stack 100h .data wax dw ? .code num proc std ; mov ax,word ptr wax ; mov dx,word ptr wax+2 ; WAX - число ES:DI-куда писать ответ ; Запись справа налево для STOSB push ax mov al,'$' stosb pop ax mov bx,10 ; Делитель diving: ; xor dx,dx ; Чтобы избежать переполнения при делении div bx ; AX=частное DX=остаток ; DX=DL % 10 push ax mov ax,dx add al,'0' stosb ; AX -> [ES:DI] ; DEC DI pop ax or ax,ax ; Частное было равно нулю? jnz diving ; Нет-продолжить цикл push ds push es pop ds mov dx,di mov ah,9 int 21h pop ds ret num endp main: mov ax,@data mov ds,ax ; mov wax,77777 mov ax,45 mov dx,23 call num mov ax,4c00h int 21h end main
giskar div работает не с ax, а с ax:dx -- в dx находятся старшая часть слова. В твоем случае ты пытаешься разделить число 0x2D0017 (2949143) на 10. Это равно 0х48002 (294914), т.е. число, большее вместимости двух байт (0xFFFF) отсюда и ошибка.
Mika0x65 Не понимаю, откуда ты берёшь число 0х2D0017. У меня есть двойное слово dx:ax, соответственно число 23:45 (2345). В hex это будет 929. Его мы и делим на 10. Кажется так, или нет?
Посмотрите пожалуста ещё этот код, вроде выводит числа максимум до 0FFFFFh. Code (Text): .model small .586 .stack 100h .data wax dw ? divident dword 0FFFFFh quotent qword ? modulo word ? .code num proc std push ax mov al,'$' stosb pop ax mov bx,10 mov ax,word ptr divident+2 xor dx,dx div bx mov ax,word ptr divident div bx io: push ax mov ax,dx add al,'0' stosb pop ax or ax,ax ; Частное было равно нулю? jnz diving jmp up diving: xor dx,dx ; Чтобы избежать переполнения при делении div bx ; AX=частное DX=остаток jmp io up: push ds push es pop ds mov dx,di mov ah,9 int 21h pop ds ret num endp main: mov ax,@data mov ds,ax call num mov ax,4c00h int 21h end main
И объясните пожалуста как нужно делить, если одна часть находится в одном регистре, а другая - в другом?
Не понял, как по-твоему лежит число в двух регистрах. Например, есть число 124696361 или 76EB729h. Если его положить в DX:AX, то DX=076eh AX=0b729h. Дальше можно его делить на 16-разрядный регистр. Например, BX=10, div bx даст... INT 0 - частное не влезает в 16 бит
Укажите пожалусна на ошибку, и посмотрите на коментарии - всё ли верно? Программа выдаёт на экран число 65538, почему так?( Code (Text): .model small .586 .stack 100h .data divident dd 0FFFFFFFFh q dw ? .code num proc std push ax mov al,'$' ; в конец строки записываем "$" stosb pop ax mov bx,10 ; делитель div bx ;делим 10002 на 10 io: push ax mov ax,dx ; в ax кладём остаток add al,'0' stosb ; в es:[di] теперь первая часть нашего десятичного числа ; и di уменьшается на единицу (так?) pop ax or ax,ax ; Частное было равно нулю? jnz diving ; если нет - снова делим, теперь уже ax на 10 (нужно ли теперь обнулять dx?) jmp up ; если да - выводим наше десятичное число на экран diving: xor dx,dx ; Чтобы избежать переполнения при делении div bx ; AX=частное DX=остаток jmp io up: push ds push es pop ds mov dx,di mov ah,9 int 21h pop ds ret num endp main: mov ax,@data mov ds,ax mov ax,2 ; в dx :ax находится число 10002, так? mov dx,1 ; его мы и делим на 10. call num mov ax,4c00h int 21h end main
Вы меня удивляете своими высказываниями.. И при этом же пишите достаточно сложные алгоритмы _правильно_. Как это возможно, откройте тайну? Или это обычный копипаст откуда-то?
Ура! Я её всё-таки написал.Спасибо Vov4ick-у, процедура, которую он тогда написал очень помогла)). mathio, ну вы поймите, если я не буду задавать такие глупые вопросы, то никогда не научусь ничему) Вот верный код: Code (Text): .model small .586 .stack 100h .data divident dd 0FFFFFFFFh quotent dd 0 modulo dw ? .code num proc std push ax mov al,'$' stosb pop ax mov bx,10 mov ax,word ptr divident+2 xor dx,dx div bx mov word ptr quotent+2,ax mov ax,word ptr divident div bx mov word ptr quotent,ax mov modulo,dx ; теперь остаток в modulo ; а частное в quotent io: mov ax,word ptr quotent+2 mov dx,word ptr quotent push ax mov ax,modulo add al,'0' stosb pop ax mov word ptr quotent+2,ax mov word ptr quotent,dx cmp quotent,0 ; Частное было равно нулю? jnz diving jmp up diving: mov ax,word ptr quotent+2 xor dx,dx ; Чтобы избежать переполнения при делении div bx mov word ptr quotent+2,ax mov ax,word ptr quotent div bx mov word ptr quotent,ax mov modulo,dx ; теперь остаток в modulo ; а частное в quotent jmp io up: push ds push es pop ds mov dx,di mov ah,9 int 21h pop ds ret num endp main: mov ax,@data mov ds,ax call num mov ax,4c00h int 21h end main