Интересное задание не могу разобраться - Assembler

Узнай цену своей работы

Формулировка задачи:

Всем доброго времени суток. Люди добрые имеется задание: На промежутке от -128 до 127 Подсчитать количество таких пар чисел X и Y, что (|Х|-|У|)mod4 =0 Ответ вывести на экран Мои наработки в Delphi с asm вставкой:
program lab3_asm;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  System.SysUtils;
 
//const
//  startint = -128;
//  endint = 127;
 
var
  x  : Integer;
  x1, x2, histAX, n : SmallInt;

begin
 asm
      mov ecx, 0
      mov cx, 256
      mov si, 0
 
      @loopAX:
        mov ax, -129
        add ax, cx
        push cx //запоминаем сх (стек)
        cmp ax, 0
        mov histAX, ax
        jg @loopBX //если больше нуля то перепрыгиваем дальше
        neg ax //иначе меняем знак и идем дальше
        mov histAX, ax
 
      @loopBX:
        mov bx, -129
        add bx, cx
        cmp bx, 0
        jg @loopMath //если больше нуля то перепрыгиваем дальше
        neg bx  //иначе меняем знак и идем дальше
 
      @loopMath:
        mov ax, histAX
        sub ax,bx
        mov bl, 4
        idiv bl
        cmp ah, 0 //если остаток от деления <> 0
        jne @loopEnd //перепрыгиваем на loopEnd
        inc si //иначе инкрементируем si и идем дальше
 
      @loopEnd:
        loop @loopBX
        pop cx
        loop @loopAX
 
        mov word ptr x, si
        mov a, ax
        mov b, bx
    end;
 Writeln('si = ' + IntToStr(x));
    Writeln('');
    Writeln('X(ax) = ' + IntToStr(a));
    Writeln('Y(bx) = ' + IntToStr(b));
    Writeln('');
  //  Writeln('ah = ' + IntToStr(q));
 
    writeln('Для завершения нажмите ENTER...');
    Writeln('');
    readln;
end.
Решил задачу на Delphi при условии (|Х|-|У|)mod4 =0 в циклах выдает 4096 раз удовлетворение условия. Данный код представленный выше написанный asm вставкой, SI= 8320раз Помогите разобраться где что не так считаю ((((( С асм новичек, только разбираюсь.

Решение задачи: «Интересное задание не могу разобраться»

textual
Листинг программы
asm
    mov ecx, 0
    mov cx, 256
    mov esi, 0
 
    @loop1:
      mov ax, cx  // AX = x + 129
      sub ax, 129 // AX = x
      cmp ax, 0 //забираем АХ для сравнения его с нулём
      jg @cont1 //если АХ положительный то перепрыгиваем на @cont1
      neg ax //иначе меняем знак AX на противоположный
      @cont1:
      push cx //запоминаем значение счетчика первого цикла
      mov cx, 256 //выставляем значение счетчика для второго цикла (цикл в цикле)
      @loop2:
        mov bx, cx  // BX = y + 129 
        sub bx, 129 // BX = y
        cmp bx, 0 //забираем ВХ для сравнения его с нулём
        jg @cont2 //если АХ положительный то перепрыгиваем на @cont2
        neg bx //иначе меняем знак AX на противоположный
        @cont2:
        push ax //запоминаем значение АХ (кладем в стек), так как расчеты у нас будут проводиться в регистре АХ
        sub ax, bx //Выполняем первое действие формулы (Х-У)
        mov dx, 0 //Зануляем регистр DX чтобы не возникало никаких ошибок
        mov bx, 4 //В регистр BX кладем "4" для дальнейшего деления
        idiv bx //делим AX на BX
        pop ax //Возвращаем из стека сохраненное значение АХ
        cmp dx, 0 //При делении остаток от деления у нас остается в регистре DX берем DX для сравнение его с нулём
        jne @endloop2 //Если остаток от деления не равно 0 тогда перепрыгиваем на @endloop2
        inc esi //Иначе увеличиваем счетчик пар на единицу
      @endloop2: loop @loop2
      pop cx //Достаем из стека сохраненное значение первого счетчика
    @endloop1: loop @loop1 //Выполняем все заного
      mov dword ptr count, esi //После завершения двух циклов переносим значение счетчика пар в переменную count для дальнейшего отображения результата средствами Delphi
    end;

Объяснение кода листинга программы

  1. Переменная ecx инициализируется значением 0.
  2. Переменная cx инициализируется значением 256.
  3. Переменная esi инициализируется значением 0.
  4. Цикл loop1:
    • Переменная ax инициализируется значением cx.
    • Значение ax уменьшается на 129.
    • Проверка: если ax больше 0, то переход к cont1.
    • Знак ax меняется на противоположный.
    • Переменная cx уменьшается на 1.
    • Если cx больше 0, то цикл продолжается, иначе цикл завершается.
  5. Цикл loop2:
    • Переменная bx инициализируется значением cx.
    • Значение bx уменьшается на 129.
    • Проверка: если bx больше 0, то переход к cont2.
    • Знак bx меняется на противоположный.
    • Переменная dx инициализируется значением 0.
    • Переменная bx инициализируется значением 4.
    • Выполняется деление ax на bx.
    • Значение ax возвращается из стека.
    • Проверка: если остаток от деления не равен 0, то цикл продолжается, иначе цикл завершается.
    • Переменная esi увеличивается на 1.
  6. Значение переменной count устанавливается равным значению переменной esi.
  7. Цикл завершается.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.385 из 5
Похожие ответы