Нужна помощь по асеблеру
Суть проблемы.
Пишу на С со вставкой асеблера, элементарная функция, но есть один косяк.
#include <stdio.h>
#include <conio.h>
void main(void)
{
int a;
int b;
int c;
int d;
int e;
int y;
__asm
{
// Сохранение в стеке текущих значений
// регистров
push eax;
push ebx;
push ecx;
push edx;
// Загрузка значений
mov a, 0x40;
mov b, 0x30;
mov c, 0x03;
mov d, 0x02;
mov e, 0x01;
// Сложение
/*функция 1) y=a+b-c*d/e */
mov eax, c; // eax = c
mov ebx, d; // ebx = d
imul eax, ebx; // eax = eax * ebx
mov ebx, e; // ebx = e
div ebx; // eax = eax / ebx
mov ecx, eax; // ecx = eax
mov eax,b; // eax = b
sub eax,ecx; // eax = eax - ecx
mov ebx, a; // ebx = a
add eax, ebx; // eax = eax + ebx
mov y, eax; // y = eax
// Восстановление из стека сохраненных значений
// регистров
pop ebx;
pop eax;
pop ecx;
pop edx;
}
printf("a = %x\nb = %x\nc = %x\nd= %x\n", a, b, c,d);
printf("y= %x\n",y);
getch();
}
Проблема в следующем. Если перед делением в регистр ebx занести значение 1, то прога после деления выдает ошибку
ас если там будет другое целое значение напрмер 2 или 3, то раьотает все нормально. Подскажите кто знает.
MOV EBX,3 ;Деление на З.
MOV EDX,0
DIV EBX
MOV RES,EAX
Не понятно зачем здесь в принципе __asm вставка.
Если для скорости - то при [Release /Of /Ot] компиляции тот же код на С++ будет значительно быстрее.
Быстродействия можно добится только использование *.obj файлов, сделанных на ASM в С++ проектах.
Если для скорости - то при [Release /Of /Ot] компиляции тот же код на С++ будет значительно быстрее.
Да тут не быстродейтвие - это у меня лаба такая, учу асеблер :)
Тогда советую поискать в Инете С++ компилятор, у корого есть опции перевода кода в assembler.
Я про это в книге "Оптимизация программ на С++" по моему видул.
Команда DIV выполняет деление целого числа без знака, находящегося в регистрах EDX:EAX, на операнд (целое без знака)
(с) документация.
#pragma argsused
int main(int argc, char* argv[])
{
int a;
int b;
int c;
int d;
int e;
int y;
__asm
{
// Сохранение в стеке текущих значений
// регистров
push eax;
push ebx;
push ecx;
push edx;
// Загрузка значений
mov a, 0x40;
mov b, 0x30;
mov c, 0x03;
mov d, 0x02;
mov e, 0x01;
// Сложение
/*функция 1) y=a+b-c*d/e */
mov eax, c; // eax = c
mov ebx, d; // ebx = d
[COLOR=Red]mul eax, ebx; // edx:eax = eax * ebx[/COLOR]
mov ebx, e; // ebx = e
[COLOR=Red]div ebx; // edx:eax = eax / ebx[/COLOR]
mov ecx, eax; // ecx = eax
mov eax,b; // eax = b
sub eax,ecx; // eax = eax - ecx
mov ebx, a; // ebx = a
add eax, ebx; // eax = eax + ebx
mov y, eax; // y = eax
// Восстановление из стека сохраненных значений
// регистров
pop ebx;
pop eax;
pop ecx;
pop edx;
}
printf("a = %x\nb = %x\nc = %x\nd= %x\n", a, b, c,d);
printf("y= %x\n",y);
return 0;
}
У меня есть Александр Крупник - "Ассемблер. Самоучитель", формат djvu. Вроде неплохо. Если надо -- пиши в перс.
Add: Год издания 2005.
У меня тут снова вопрос... опять С, вставка асеблера, в асме считается какое то выражение, меняется i - счетчик цикла, a - изменяющая переменная и y - результат вычисления выражения при заданном a. Собственно вопрос: нужно вывести результат в виде одного массива, содержащего n троек значений "порядковый номер – аргумент - функция". Не подскажете как реализовать?
0)возвращать указатель на массив.При этом функция должна сама выделить себе память под него,а потом как-то позаботиться о её освобождении(например,пользователь будет вызывать сначала твою функцию,а после использования массива–функцию CleanUp,которая освободит выделенную функцией память).Так обычно не поступают
1)в функцию должен передаваться указатель на массив,созданный пользователем,и его длина.В таком случае ты просто пишешь свои n троек значений по этому адресу и ни на чём не заморачиваешься.Но придётся дать пользователю возможность узнать,достаточное ли количество памяти он выделил под массив
Такой метод используется очень часто.Достаточно посмотреть на реализацию некоторых API-функций,чтобы убедиться в том,что парни из Microsoft тоже решили не заморачиваться(например,EnumProcesses;почитай к ней описание,дабы разобраться,как реализовывать сей метод)
Итак,начнём.Регистру никакому присваивать сей указатель не надо(в смысле,необязательно)–тебе просто по тому адресу,который передан в процедуру,надо записать свои данные.Ведь это как будет выглядеть?А вот примерно вот так:
[SIZE="1"]Прошу прощения за тот бред,что я сейчас написал;примерно так должно выглядеть описание функции[/SIZE]
Так вот,*ArrAddr и будет тем адресом массива,который сгенерирован снаружи функции и будет передан ей в качестве 2го параметра.В него ты и будешь писать в ассемблерной вставке
P.S.Первые 2 части твоей идеи верные:)
И снова вопрос. Задание:
Опять нада реализовать на асме. Не пожскажите? ибо я что т и не вкурю как делать преобразование:)
Я вот не понял,как из строки символов преобразовать в "двоичный код в формате слова".Надо выводить нолики и единички в таком виде,что ли(типа словами)?
Скорее всего да.
Я написал все задание, какое было :) я еще у препода спрошу что сделать то надо.
Вообщем так: лаба, пишем в С, используя асемблерные вставки, тема Процедуры. нужно написать 3 процедуры на асме и вызов их тоже должен производиться из асеблерной вставки. С этим проблем нету, проблема в следующем. При вызове одной из функций, ее должны передаваться данные через сегмент стека, а возвращать она должна тоже через сегмент стека, но возвращать уже адреса. Собсвтено вопрос как это реализовать?
Получается что у меня при возврате в сегменте стека будет лежать адрес результата?