Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.04.2013, 16:40   #1
antoxamad
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 32
Вопрос Интересное задание не могу разобраться

Всем доброго времени суток. Люди добрые имеется задание:

На промежутке от -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раз

Помогите разобраться где что не так считаю ((((( С асм новичек, только разбираюсь.
antoxamad вне форума Ответить с цитированием
Старый 12.04.2013, 11:51   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

На этом промежутке 256 чисел, по 64 с каждым остатком от деления модуля на 4. Разность чисел делится на 4, если у обоих одинаковые остатки от деления на 4. В каждой такой группе будет
C(64; 2) = 63 * 64 / 2 = 2016
чисел. Итого 2016 * 4 = 8064.
Так что у тебя и на Delphi неправильно. А на ассемблере я что-то не понял, что такое:
Код:
mov ax, -129
add ax, cx
Как вариант:
Код:
// dl = x, dh = y, ecx = n
xor ecx, ecx
mov dl, -128
@loopX:
mov dh, dl
jmp @loopYStart
@loopY:
mov al, dl
xor al, dh
cbw
mov al, dl
xor al, ah
sub al, ah
xor al, dh
and al, 3
cmp al, 1
adc ecx, 0
@loopYStart:
inc dh
jno @loopY
inc dl
jno @loopX
mov [n], ecx
Somebody вне форума Ответить с цитированием
Старый 12.04.2013, 14:36   #3
antoxamad
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 32
По умолчанию

Поразмышляв с листочком и ручкой пришел к следующему выводу:
На промежутке от -128 до 127
Подсчитать количество таких пар чисел X и Y, что (|Х|-|Y|)mod 4 =0[list=1][*]то, что используется модуль для Х и Y говорит о том, что можно подсчитать задание для чисел от 0 до 128, а потом умножить результат на четыре.
Х | Y | N
+ | + | 1
+ | - | 2
- | + |3
- | - |4
То, что от разницы Х и Y ищется остаток от деления на 4 равный нулю говорит о том, что разницу нужно искать у чисел, которые кратны четырем, таких чисел 129/4=32 пар чисел X и Y, таких что (|Х|-|Y|)mod 4 =0 будет 32^2=1024, умножаем 1024*4=4096.

Так ли это ?
antoxamad вне форума Ответить с цитированием
Старый 12.04.2013, 15:32   #4
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,162
По умолчанию

antoxamad,
ты хоть бы автора указывал, и сайт с которого скопировал, "поразмышлял он с листочком и ручкой и пришел к следующему выводу", тупо сдул и выдал за своё

Последний раз редактировалось Mikl___; 12.04.2013 в 15:35.
Mikl___ вне форума Ответить с цитированием
Старый 12.04.2013, 15:38   #5
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

нет. например:
x = 7
y = -3

(|7| - |-3|) mod 4 = (4) mod 4 = 0

в коде это можно реализовать примерно так:

Код:
  xor bx, bx
  mov cx, 0ffffh
cyc:
  mov ax, cx
  test ah, 80h
  jnz no_sign1
  neg ah
no_sign1:
  test al,80h
  jnz no_sign2
  neg al
no_sign2:
  sub ah, al
  and al, 00000011b
  jnz to_loop
  inc bx
to_loop:
  loop cyc
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 12.04.2013, 15:46   #6
antoxamad
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 32
По умолчанию

Цитата:
Сообщение от Mikl___ Посмотреть сообщение
antoxamad,
ты хоть бы автора указывал, и сайт с которого скопировал, "поразмышлял он с листочком и ручкой и пришел к следующему выводу", тупо сдул и выдал за своё
извеняюсь канеш, но мозговал с листочком, приношу свои искренние извенения. Верхнее размышление автора "Mikl___" http://www.programmersforum.ru/member.php?u=72875 с сайта http://www.cyberforum.ru/
за что ему огромное спасибо, только на этом форуме возникают разногласия с задачей. Пока не могу сообразить почему
antoxamad вне форума Ответить с цитированием
Старый 12.04.2013, 17:41   #7
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

в принципе, Somebody абсолютно прав. для того, чтобы узнать сколько таких пар не обязательно проверять, можно и "на листочке посчитать".

а код из первого поста дает на 256 больше, потому что цикл по bx начинается не со следующего за ax значения, а с ax (тривиальный случай x = y).

Последний раз редактировалось f.hump; 12.04.2013 в 17:58.
f.hump вне форума Ответить с цитированием
Старый 14.04.2013, 12:32   #8
antoxamad
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 32
По умолчанию

Дорогие форумчане, огромное спасибо всем тем кто участвовал в помощи. Разобрался получилось следующее (может кому надо будет):
Код:
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;
Вот как то так разобрался, сильно палкой не бить. Только учусь.

Тему можно считать закрытой.
antoxamad вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
задание на C - разобраться с классом, хранящим в себе дату world12_tk Помощь студентам 7 08.10.2011 00:15
Интересное задание = ) Этотак Помощь студентам 1 10.06.2011 23:25
Для кого то интересное задание Димко90 Компоненты Delphi 2 12.12.2010 11:42
Очень интересное и творческое задание Димко90 Помощь студентам 0 12.12.2010 03:41
Интересное задание MaTpOc12 Помощь студентам 3 20.10.2010 18:10