Товарищи, ниже представлен код с ошибкой. Помогите пожалуста исправить. Две строчки с ошибками выделены и закоментированы. Не понимаю, почему не выполняется MOVZX, или, что тоже самое, word ptr wax+2,mas[4]. Как вы поняли, я хочу запихнуть слово mas[4], в младшую часть двойного слова wax. Имеют ли смысл мои попытки? в чём ошибка? Обратите внимание, что без этих двух строчек на экран выводится один массив(как мне кажется верный), но если например вставить в кок строчку MUL WAX, то на экран выведится уже другой массив( как мне кажется НЕ верный). Почему так? Код (Text): .model small .586 .stack 100h .data mes db "po umolchaniu dick C: $",0ah,0dh mas dw 4 dup(?) mus db 0Ah,0Dh,0Ah,'$' .data? wax dd ? way dd ? len dw ? .code ;вывод строки на экран sc proc mov ah,9 int 21h ret sc endp ;вывод числа из ax на экран num proc ; AX - число ES:DI-куда писать ответ std ; Запись справа налево для 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 ah,19h ;получаем номер заданного int 21h ; по умолчанию дисковода jc exit cmp al,02 ; 02 - "C:\" ;jne pul mov dl,al mov dx,offset mes call sc mov ah,36h ;получаем инфу о свободном дисковом int 21h ; пространстве ; ax - число секторов в одном кластере ; bx - количество свободных кластеров ; cx - размер сектора в байтах ; dx - общее число кластеров на диске mov esi,0 mov mas[0],ax mov mas[2],bx mov mas[4],cx mov mas[8],dx xor ax,ax mov ax,mas[0] call num ;выводим число секторов xor ax,ax mov ax,mas[2] call num ;свободных кластеров xor ax,ax mov ax,mas[4] call num ; размер сектора в байтах xor ax,ax mov ax,mas[8] call num ; и общее число кластеров ;считаем свободное пространство на диске : ax*bx*cx xor ax,ax mov ax,mas[0] mul mas[2] mov word ptr wax,dx mov word ptr wax+2,ax ;теперь в wax находится ax*bx xor ax,ax xor dx,dx mov eax,wax ;теперь в eax находится ax*bx mov wax,0 ;MOVZX WAX,MAS[4] ;в wax находится cx ? ;MUL WAX ;умножаем cx на ax*bx ? exit: mov ah,10h int 16h mov ax,4c00h int 21h end main
1) используйте регистр, mov не может писать из памяти в память только через регистр 2)как он ругается на строку "MUL WAX"? с размерностью не напутали? 3) cx, ecx в процессе выполнения команды mul не используется
Ага, всё исправил.Спасибо. А не подскажите как при выполнении программы перейти на другую строку в командной строке, ну т.е. у меня, как видите в программе выводится строка "po umolchaniu dick C:", а затем сразу после неё выводятся элементы массива mas, а я хочу, что бы элементы массива выводились уже на другой строчке. Не подскажите как это сделать?
MultiString db "line1", 0dh, 0ah, "line2" вообще-то управляющие символы расписаны в любом мало-мальском учебнике по ассемблеру
Найди старые, но мощные доки вроде TechHelp!, HelpPC, Журдена и прочие хорошие книжки. Их в инете много.
почему то асм не сравнивает 64-разрядную переменную quotent типа qword с нулём: cmp quotent,0 jnz io На это он выдаёт ошибку A2070. Объясните в чём моя ошибка?
на х86 нету 64битных регистров и соответственно таких возможностей сравнивай по частям либо через cmps, ну или купи новый камень и программируй в родном для него режиме
Посмотрите пожалуста код. Прога должна вывести в десятиричном виде число divident. Собственно она это похоже и делает(жаль не могу проверить - в калькуляторе только 9-ть цифр), но с глюками: число почемут выводится несколько раз, с какими-то буковками, и прога зависает. Вобщем сассемблируйте и посмотрите пожалуста что не так. Вот код с коментариями: Код (Text): .model small .586 .stack 100h .data divident qword 0FFFFFFFFFFFFFFFFh quotent qword ? modulo dw ? ha dword 00000000h .code num2 proc std ; push ax ; для вывода строки mov al,'$' ; на экран stosb ; pop ax ; mov bx,10 ; делим на 10 ;начинаем делить xor ax,ax mov ax,word ptr divident+6 xor dx,dx div bx mov word ptr quotent+6,ax xor ax,ax mov ax,word ptr divident+4 div bx mov word ptr quotent+4,ax xor ax,ax mov ax,word ptr divident+2 div bx mov word ptr quotent+2,ax xor ax,ax mov ax,word ptr divident div bx mov word ptr quotent,ax mov modulo,dx ; теперь остаток в modulo ; а частное в quotent io: ; mov eax,dword ptr quotent+8 ; сохраняем частное ; mov edx,dword ptr quotent push ax ; ; xor ax,ax ; выводим первую часть ; нашего числа mov ax,modulo ; (и далее последущие см. ниже) ; add al,'0' ; ; stosb ; ; pop ax ; ; mov dword ptr quotent+8,eax ; mov dword ptr quotent,edx push eax ; начинаем проверять quotent ; на равенство нулю по частям xor eax,eax ; ; mov eax,dword ptr quotent ; первая часть: cmp eax,ha ; Частное было равно нулю? jnz diving ; не равно ; xor eax,eax ; ; mov eax,dword ptr quotent+8 ; вторая часть: cmp eax,ha ; Частное было равно нулю? jnz diving ; не равно jmp up diving: ;quotent не был равен нулю - делим дальше pop eax xor ax,ax mov ax,word ptr quotent+6 xor dx,dx div bx mov word ptr quotent+6,ax xor ax,ax mov ax,word ptr quotent+4 div bx mov word ptr quotent+4,ax xor ax,ax mov ax,word ptr quotent+2 div bx mov word ptr quotent+2,ax xor ax,ax mov ax,word ptr quotent div bx mov word ptr quotent,ax mov modulo,dx ; теперь остаток в modulo ; а частное в quotent jmp io up: ; выводим строку из es:di на экран push ds push es pop ds mov dx,di mov ah,9 int 21h pop ds ret num2 endp main: mov ax,@data mov ds,ax call num2 mov ah,10h int 16h mov ax,4c00h int 21h end main
Код (Text): mov eax,dword ptr quotent+8 ; вторая часть: Почему 'quotent+8'? Должно быть 'mov eax,dword ptr quotent + 4'. Ну и по-мелочи: 1. Очищать регистр перед использованием не нужно. Т.е. в Код (Text): xor eax,eax ; mov eax,dword ptr quotent ; первая часть: 'xor eax, eax' не нужен. 2. Переменная 'ha' тоже не нужна -- команда cmp умеет работать с непосредственными операндами, т.е. можно заменить на 'cmp eax, 0x0'. 3. Стек будет несбалансированным, при при выходе по 'jmp up' -- тогда у инструкции 'push eax' не будет пары 'pop xxx'. От этого можно избавиться, заменив Код (Text): mov eax,dword ptr quotent ; первая часть: cmp eax,ha ; Частное было равно нулю? jnz diving на Код (Text): cmp dword ptr quotent,0x0 ; Частное было равно нулю? А вообще, это что новый способ деления больших чисел?
Mika0x65 Ага, спасибо, всё исправил, всё работает)) А вобще, это я 64-разрядное число на экран просто хочу уметь выводить) Я не знаю, может быть существует способ и покороче, кроме как делить это число на 10 всё время) Ну можно ещё сдвигами, но я в них чё т не разобрался)
Сдвиги - не что иное, как деление на число, равное степени двойки (2, 4, 8, 16...), используются при выводе чисел в системе счисления с основанием, равным степени двойки. 10 - это не степень двойки, поэтому на сдвиг прямо не заменяется.