Page 4 of 12

Re: Начинающий

Posted: Tue Aug 25, 2009 1:27 pm
by Albom
результат принято передавать в регистре eax (хотя никто не запрещает использовать другие регистры - лишь бы они не использовались в основной программе, а если используются, то нужно сохранять их, например, в стеке). но во-первых, ты написал, что ф-ция ничего не возвращает (void), а во-вторых, речь шла о входных параметрах, а не выходных. так что поконкретнее плиз.

Re: Начинающий

Posted: Tue Aug 25, 2009 1:29 pm
by Albom
вообще, почти все компиляторы могут создавать ассемблерный листинг. так что изучай его.

Re: Начинающий

Posted: Tue Aug 25, 2009 1:43 pm
by IgorA
Интересует преобразование дробных чисел в целые, и обратно.
Как можно преобразовать 2-х байтное целое число в 4-х байтное дробное (с плавающей точкой). И как потом обратно из плавающего записать в 2-х байтное целое.
Хочу сделать программу, которая будет выводить на экран графическую информацию, предварительно расчитав координаты. Дело в том что сопроцесор работает с дробными числами, а при выводе на экран нужны целочисленные координаты.
Пока нигде подобного не нашел, но ведь должны быть какие-то способы это делать? Писать свою функцию для преобразования не хочу, потому-что это неэфективно, и наверняка должны быть какие-то другие способы.

Например на С++ делается так:

Code: Select all

float a=1.2345; // дробное число
short int b;
//a=... // пошли вычисления
b=(short int)a; // приведение дробного к целому, как оно его делает ???
Как то же самое будет выглядеть на asm? Думал что так:

Code: Select all

  fldpi ;загрузка дробного числа
  fist word [bx] ;преобразовать к 2-х байтному ???
но ничего не получаеться. В справочнике информации мало:
FIST Запись целого значения.
...
FIST приемник

Re: Начинающий

Posted: Tue Aug 25, 2009 2:03 pm
by diamond
IgorA wrote:Интересует преобразование дробных чисел в целые, и обратно.
Это делается именно командами fild, fist, fistp. Первая загружает целое число (16-битное или 32-битное) в вершину стека сопроцессора, преобразуя его в вещественный формат. Вторая и третья записывают число с вершины стека сопроцессора в указанную ячейку памяти (16- или 32-битную), при этом fist не меняет стека сопроцессора, fistp выталкивает число с вершины. Режим преобразования - округление вверх, вниз, к ближайшему целому - можно установить через fldcw, по умолчанию finit устанавливает округление до ближайшего.
Есть ещё frndint, она округляет до целого число в вершине стека сопроцессора.
IgorA wrote:но ничего не получаеться
Что именно не получается? Кстати, использование адресации [bx] в 32-битном коде - не лучшая идея.

Re: Начинающий

Posted: Tue Aug 25, 2009 2:57 pm
by Yaskhan
так что поконкретнее плиз.
Ну как такое тогда делать? Если ничего нельзя возвращать? Как в ассемблере делать &?

Re: Начинающий

Posted: Tue Aug 25, 2009 3:42 pm
by IgorA
diamond wrote:Что именно не получается?
Сделал пробный пример, вывожу 2 надписи на экран (синего и красного цвета). Одну из координат 1-й надписи задаю дробным числом, а перед выводом на экран преобразовываю к целому числу.
Координаты 2-й надписи даю точно такие-же, но сразу все координаты целые по 2 байта.
По идее надписи должны попасть в одно место (все координаты равны). Но оно не попадает, вывод - не правильно преобразовал дробное число к целому.
Yaskhan wrote:Если ничего нельзя возвращать? Как в ассемблере делать &?
Посмотри ниже прикрепленный файл, там речь идет о разных способах передачи параметров в функцию.

Re: Начинающий

Posted: Tue Aug 25, 2009 3:47 pm
by diamond
IgorA
А, ясно. Сопроцессор не может сохранять значения из своего стека напрямую в регистры центрального процессора, а может только в память. Соответственно fist word [bx] сохраняет, в полном соответствии с синтаксисом команды (квадратные скобки неспроста), значение в память по адресу, находящемуся в bx, а вовсе не в bx. Чтобы получить значение в bx, нужно сохранить из стека в промежуточную переменную, а потом загрузить сохранённое значение в bx.

Re: Начинающий

Posted: Tue Aug 25, 2009 3:50 pm
by Albom
Yaskhan wrote:Как в ассемблере делать &?
простой пример:

Code: Select all

org 0x100
Var1 dd 0x102
mov dword eax, [Var1] ; в eax будет значение переменной, т.е. 0x102
mov dword eax, Var1   ; в eax будет адрес переменной, т.е. 0x100

Re: Начинающий

Posted: Wed Aug 26, 2009 10:43 pm
by ChE
Сегодня долго не мог понять, почему не работает программа. Вы не представляете, как долго я долбился. Код заработал, когда поменял

Code: Select all

...
mcall 68, 12, eax
...
на

Code: Select all

...
mov  ecx, eax
mcall 68, 12
...
А я и не знал, что так нельзя :o

Re: Начинающий

Posted: Thu Aug 27, 2009 12:46 am
by Mario
ChE
Конечно нельзя!
Первым же действием макрос затирает значение EAX прописывая в регистр 68.
Наверное все таки стоит смотреть код макроса перед тем, как им пользоваться?

Вообще макрос это кусок кода, который тупо вставится вместо того, что ты написал и ожидать от него особо интеллектуального поведения не имеет смысла.

Re: Начинающий

Posted: Thu Aug 27, 2009 6:42 am
by ChE
Блин, сегодня проснулся со свежей головой и понял свою тупость вчерашнюю.

Re: Начинающий

Posted: Fri Aug 28, 2009 9:15 am
by Asper
IgorA wrote:В справочнике информации мало
Смотри файл "Инструкции IA.doc" в архиве.
ftp://kolibrios.org/users/Asper/docs/mydocs.7z

Re: Начинающий

Posted: Mon Aug 31, 2009 3:29 pm
by Leency
Я перевожу Эолайт с ASCII-символов на Скан коды. Вопрос: как преобразовывать Скан-коды в ASCII-символы? Я так понял, это требуется, например, для Edit_box'a.

Re: Начинающий

Posted: Mon Aug 31, 2009 3:52 pm
by Mario
Leency
В дистрибутиве есть два приложения, одно генерирует коды ASCII, другое Scan. Называются keyascii и scancode соответсвенно. Дальше сам разберешся? :mrgreen:

Re: Начинающий

Posted: Thu Sep 03, 2009 10:37 pm
by IgorA
Есть код рисующий кривые Безье:

Code: Select all

void TMyWin::Bezie(TDC& dc, float x0, float y0, float x1, float y1, float x2, float y2)
{
    dc.Ellipse(x0-3,y0-3, x0+3,y0+3);
    dc.Ellipse(x1-3,y1-3, x1+3,y1+3);
    dc.Ellipse(x2-3,y2-3, x2+3,y2+3);

    float t, xt,yt;
    for(t=.0;t<1.;t+=.005){
      xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
      yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
      dc.SetPixel(xt,yt,255L);
}}
Вопрос в том как можно определить шаг для изменения переменной t (t+=.005) ? Если задать его константой, то при большом разбросе точек кривая "рвется", а при маленьком точки налазят друг на друга и многие точки зря рисуются ... Может кто знает как подобная проблема решается в WinAPI?
Все это дело я попробую при возможности включить в vectors.obj