Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Профессор
Рейтинг: 2739
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2636
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2131
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1472
Дата выхода:16.09.2011, 20:30
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:200 / 62
Вопросов / ответов:1 / 1

Консультация # 184006: Здравствуйте! У меня возникли сложности с таким вопросом: Необходимо реализовать программы с помощью Ассемблера (как вставка в Паскаль) 1. Вычислить: (A * X^2 + B * X + C) div (D * X + E), где переменные задаются с клавиатуры 2. вычислить: "Знак суммы" (Ai * Bij) * X + "знак суммы" (Ci) * Y,...


Консультация # 184006:

Здравствуйте! У меня возникли сложности с таким вопросом:
Необходимо реализовать программы с помощью Ассемблера (как вставка в Паскаль)
1. Вычислить: (A * X^2 + B * X + C) div (D * X + E), где переменные задаются с клавиатуры

2. вычислить: "Знак суммы" (Ai * Bij) * X + "знак суммы" (Ci) * Y, где A B C - массивы. Если у массива указан один индекс, значит он одномерный, если два – двумерный. Индекс i и j=1..3.

3. Реализуйте с помощью логических симметричное отображение младшего байта слова на старший байт с потерей исходных значений.

Заранее благодарю.

Дата отправки: 11.09.2011, 20:09
Вопрос задал: Посетитель - 380267 (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Посетитель - 380267!
1) Даю целых три варианта, выбирайте, что Вам нравится:
а) Результат - вещественное число, весь расчет в сопроцессоре;
б) Результат - вещественное число, расчет целочисленных делителя и делимого, деление в сопроцессоре;
в) Результат - целое число.
Для сравнения, также привожу паскалевский расчет.

Код :
program q184006_1;

{$mode objfpc}{$H+}
{$ASMMODE intel}

var
  A,B,C,D,E,X:Integer;
  Res:Double;

{(A * X^2 + B * X + C) div (D * X + E)}
{расчет в сопроцессоре, параметры в стеке}
{результат - вещественное число в регистре st}
function CalcVar1(A, B, C, D, E, X:Integer):double; stdcall; Assembler;
asm
   finit
   fild  X  {st = x}
   fld   st  {st = x, st(1) = x}
   fld   st  {st = x, st(1) = x, st(2) = x}
   fmulp st(1)  {st = x^2, st(1) = x}
   fimul A  {st = A*x^2, st(1) = x}
   fild  B  {st = B, st(1) = A*x^2, st(2) = x}
   fmulp st(2)  {st = B*x, st(1) = A*x^2}
   faddp st(1)  {st = B*x + A*x^2}
   fiadd C  {st = B*x + A*x^2 + C}
   fild  X  {st = x, st(1) = B*x + A*x^2 + C}
   fimul D  {st = D*x, st(1) = B*x + A*x^2 + C}
   fiadd E  {st = D*x + E, st(1) = B*x + A*x^2 + C}
   fdivp st(1), st {st = (B*x + A*x^2 + C) / (D*x + E)}
end;

{(A * X^2 + B * X + C) div (D * X + E)}
{расчет делимого и делителя в процессоре, деление в сопроцессоре}
{параметры в стеке, результат - вещественное число в регистре st}
function CalcVar2(A, B, C, D, E, X:Integer):double; stdcall; Assembler;
asm
   push  esi
   push  edi
   finit
   mov   eax, X  {eax = x}
   imul  X  {edx:eax = x^2}
   {умножим x^2 на A столбиком}
   mov   edi, edx {сохраним ст слово x^2}
   imul  A  {edx:eax = A * мл слово x^2}
   mov   esi, eax {edi:esi = A * мл слово x^2}
   mov   edi, edx
   mov   eax, edi {ст слово x^2}
   imul  A  {edx:eax = A * ст слово x^2}
   add   edi, eax {столбик: добавим к ст слову (A * мл слово x^2) мл слово от (A * ст слово x^2)}
   {edi:esi = A*x^2}
   mov   eax, X  {x}
   imul  B  {edx:eax = B*x}
   add   esi, eax
   adc   edi, edx {edi:esi = A*x^2 + B*x}
   mov   eax, C
   cdq   {edx:eax = C}
   add   eax, esi
   adc   edx, edi {edx:eax = A*x^2 + B*x + C}

   sub   esp, 8  {выделим память под два слова}
   mov   [esp], eax
   mov   [esp+4], edx {[esp] = делимое}
   fild  qword ptr [esp]{st = делимое}

   mov   eax, X  {x}
   imul  D  {edx:eax = D*x}
   mov   [esp], eax {сформируем в [esp] делитель}
   mov   [esp+4], edx
   mov   eax, E
   cdq   {edx:eax = E}
   add   [esp], eax
   adc   [esp+4], edx {[esp] = D*x + E}
   fild  qword ptr [esp]{st = делитель, st(1) = делимое}
   fdivp st(1), st {st = (A*x^2 + B*x + C) / (D*x + E)}

   add   esp, 8  {уберем из стека буфер}
   pop   edi
   pop   esi
end;

{(A * X^2 + B * X + C) div (D * X + E)}
{расчет полностью целочисленный}
{параметры в стеке, результат - частное (целое число) в регистре eax, частное отбрасывается}
{предполагаем, что делитель D*X+E помещается в одно слово}
function CalcVar3(A, B, C, D, E, X:Integer):Integer; stdcall; Assembler;
asm
   push  esi
   push  edi

   mov   eax, X
   imul  D
   add   eax, E
   mov   ecx, eax {делитель ecx = D*x + E}

   {считаем делимое}
   mov   eax, X  {eax = x}
   imul  X  {edx:eax = x^2}
   {умножим x^2 на A столбиком}
   mov   edi, edx {сохраним ст слово x^2}
   imul  A  {edx:eax = A * мл слово x^2}
   mov   esi, eax {edi:esi = A * мл слово x^2}
   mov   edi, edx
   mov   eax, edi {ст слово x^2}
   imul  A  {edx:eax = A * ст слово x^2}
   add   edi, eax {столбик: добавим к ст слову (A * мл слово x^2) мл слово от (A * ст слово x^2)}
   {edi:esi = A*x^2}
   mov   eax, X  {x}
   imul  B  {edx:eax = B*x}
   add   esi, eax
   adc   edi, edx {edi:esi = A*x^2 + B*x}
   mov   eax, C
   cdq   {edx:eax = C}
   add   eax, esi
   adc   edx, edi {edx:eax = A*x^2 + B*x + C}

   idiv  ecx  {eax = edx:eax / ecx}

   pop   edi
   pop   esi
end;

begin
  { Вводим переменные }
  Write('A = '); ReadLn(A);
  Write('B = '); ReadLn(B);
  Write('C = '); ReadLn(C);
  Write('D = '); ReadLn(D);
  Write('E = '); ReadLn(E);
  Write('X = '); ReadLn(X);

  {проверим, нет ли деления на 0}
  if D*X+E <> 0 then
     begin
      {посчитаем в Паскале} 
       Res := (A*X*X + B*X + C) / (D*X + E);
       {вывод паскалевской вещественной переменной}
       WriteLn('Result Pas = ', Res:10:6);
       {весь расчет в сопроцесоре}
       WriteLn('Result Asm1 = ', CalcVar1(A, B, C, D, E, X):10:6);
       {расчет целочисленных делителя и делимого, деление в сопроцессоре}
       WriteLn('Result Asm2 = ', CalcVar2(A, B, C, D, E, X):10:6);
       {целочисленное деление}
       WriteLn('Result Asm3 = ', CalcVar3(A, B, C, D, E, X))
     end
  else
     Write('Division by 0');
  ReadLn;
end.


2) Ищем суммы, которые умножаем на X и Y, соответственно, которые потом тоже складываем.

Код :
program q184006_2;

{$mode objfpc}{$H+}
{$ASMMODE intel}

const
  { Размерность массива }
  N=3;

type
  TMatrix=array[1..N,1..N]of Integer;  { Тип - матрица }
  TVector=array[1..N]of Integer;       { Тип - вектор }

var
  A,C:TVector;  { Вектора}
  B:TMatrix;            { Матрица }
  I,J,X,Y:Integer;

{sum( (Ai * Bij) * X ) + sum( (Ci) * Y )}
{Расчет ведется следующим образом:}
{1) находим s1=SUM(j=1..3)SUM(i=1..3)(A[i]*B[i,j])}
{2) s1 = s1*X}
{3) находим s2=SUM(i=1..3)(C[i])}
{4) s2 = s2*Y}
{5) Результат s1+s2}
function CalcSum(A:TVector; B:TMatrix; C: TVector;  X, Y:Integer):Integer; stdcall; Assembler;
  asm
     push  esi
     push  edi
     push  ebx

     xor   ebx, ebx  {искомая сумма}

     mov   ecx, 3  {счетчик столбцов в массиве B}
     xor   edi, edi  {индекс элемента (i*N + j) в массиве B}
 sumLoop1:   {цикл по столбцам j массива B}
     push  ecx   {сохраним счетчик столбцов в массиве B}
     xor   ecx, ecx  {индекс в массиве A, i}
     mov   esi, A  {адрес массива А}
     push  edi   {сохраним индекс первого элемента в столбце}
 sumLoop2:   {цикл по строкам i массива В}
     mov   eax, [esi+ecx*4] {элемент массива А, ECX = i}
     mov   edx, B  {адрес массива В}
     imul  dword ptr[edi*4+edx] {eax = A[i]*B[i*N+j]}
     add   ebx, eax  {накапливаем сумму}
     add   edi, N  {на следующий элемент столбца, i=i+1}
     inc   ecx   {на следующий элемент массива А}
     cmp   ecx, N  {прошли все строки у столбеца и массив А?}
     jb    @sumLoop2  {нет - на повтор}
     pop   edi   {восстанавливаем индекс первого элемента в столбце}
     inc   edi   {на следующий столбец массива В}
     pop   ecx   {восстанавливаем счетчик столбцов в массиве B}
     loop  @sumLoop1  {по всем столбцам}

     mov   eax, ebx  {посчитанная сумма}
     imul  x   {умножаем на Х}
     mov   ebx, eax  {сохраним}

     xor   eax, eax  {посчитаем sum(ci)}
     mov   edi, C  {адрес массива С}
    {после последнего loop, ECX=0}
 sumLoop:   {цикл по элементам массива}
     add   eax, [edi+ecx*4] {складываем, ECX = i}
     inc   ecx   {на следующий элемент}
     cmp   ecx, N  {проверим на конец}
     jb    @sumLoop
     imul  Y   {eax = sum * Y}

     add   eax, ebx  {eax = искомой сумме}

     pop   ebx
     pop   edi
     pop   esi
  end;

begin
  { Вводим данные }

  for I:=1 to N do begin
    for J:=1 to N do begin
      Write('B[',i,',',j,'] = '); ReadLn(B[i,j]);
    end;
  end;
  WriteLn;

  for I:=1 to N do begin
     Write('A[',i,'] = '); ReadLn(A[i]);
  end;
  WriteLn;

  for I:=1 to N do begin
     Write('C[',i,'] = '); ReadLn(C[i]);
  end;
  WriteLn;

  Write('X = '); ReadLn(X);
  Write('Y = '); ReadLn(Y);
  WriteLn;

  WriteLn('Result = ', CalcSum(A, B, C, X, Y));

  ReadLn;
end.


На вопрос №3 дан ответ здесь

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 12.09.2011, 15:21

5
нет комментария
-----
Дата оценки: 12.09.2011, 23:38

Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное