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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.10.2009, 20:11   #1
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию большие числа

в общем есть такая задача написать среднее арифметическое длинных чисел используя побитовый сдвиг. Сама программа уже написана но неправильно работает. Число представляется как массив из нескольких элементов. Допустим надо вычислить ср арифм двух элементов 0xffffffff и 1
(0xffffffff+1 ) >> 1 = 0x8000000

но программа дает результат 7fffffff, то есть 0xffffffff >> 1 = 7fffffff
я так понимаю 1 не прибавляется

Для вычисления используется сложение с учетом cary флага и сдвиг вправо
adc и shr

программа используется с помощью программы на си , тип элементов unsigned int

асемблер 80836

какие есть идеи

Последний раз редактировалось NiCola999; 29.10.2009 в 20:19.
NiCola999 вне форума Ответить с цитированием
Старый 29.10.2009, 20:36   #2
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

использовать shrd
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 29.10.2009, 21:58   #3
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

мне кажется сдвиг тут не причем, надо разбираться со сложением

mov eax,0xffffffff
mov ebx,1
adc eax,ebx
shrd eax,1

выводит
ambiguous operand size or operands invalid for 'shrd'

Последний раз редактировалось NiCola999; 29.10.2009 в 22:04.
NiCola999 вне форума Ответить с цитированием
Старый 30.10.2009, 07:02   #4
Виталий Серов
Заснувший
Форумчанин
 
Регистрация: 13.03.2009
Сообщений: 213
По умолчанию

Цитата:
mov eax,0xffffffff
mov ebx,1
adc eax,ebx
shrd eax,1
SHRD - это сдвиг двойного слова вправо, тут незачем так двигать.

в третьей строчке вы используете "сложение с учётом переполнения", при этом до этой команды нет ничего, что может вызвать флаг cary может я жутко не образован, но мне кажется что надо делать примерно так...
Цитата:
add eax,edx ;прибавление числа к числу
adc eax,0 ;прибавляем 0 плюс флаг переноса если он есть
но эти команды не дадут эффекта, так как
FFFFFFFF + 1 = 0 + плюс флаг переноса
сдвинув число вправо вы всё равно получите 0.
следовательно вам нужно использывать простое деление:
Цитата:
add eax,ecx ;eax - младшие 32 бита делимого
adc edx,0 ; старшие биты делимого
mov ebx,2 ; делитель
div EBX ; деление
eax == 0x8000000

Последний раз редактировалось Виталий Серов; 30.10.2009 в 07:04.
Виталий Серов вне форума Ответить с цитированием
Старый 30.10.2009, 10:01   #5
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

угу , но в задаче сказано именно сдвигом
NiCola999 вне форума Ответить с цитированием
Старый 30.10.2009, 10:12   #6
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

угу , но в задаче сказано именно сдвигом

числа представлены в виде массивов, например таких

unsigned int a[5] = {1, 0, 0xffffffff, 0xffffffff, 0xffffffff};
unsigned int b[5] = {1, 0, 0, 0, 1};
unsigned int c[5] = {0, 0, 0, 0, 0};

моя прога выдает
1 0 0 7fffffff 0

а правильный ответ
1, 0, 8000000, 0, 0

ф-я должна складывать "в столбик" a и b и после сложения сдвинуть вправо , а флаг cary тут нужен для запоминания единички( ноль пишем один в уме =))
в общем для понимания вот моя программа

Код:
longavg:
            push ebx
            push edx
            push esi
            push ecx

# загрузка аргументов функции
            mov ebx, [esp+20] # *a
            mov edx, [esp+24] # *b
            mov esi, [esp+28]  # *c
            mov ecx, [esp+32] # size (size_a = size_b)

            clc  # clear cary
cycle:
          mov eax, [ebx+4*ecx-4]  # сохранение каждого элемента первого массива в eax для сложения
          adc eax, [edx+4*ecx-4]  # сложением с каждым элементов второго массива с учетом cary
          shr eax,1                       
          mov [esi+4*ecx-4],eax   # в массив c кладется результат
          loop cycle # ecx --

          mov eax,esi
          pop ebx
          pop edx
          pop esi
          pop ecx
          ret

Последний раз редактировалось NiCola999; 30.10.2009 в 10:28.
NiCola999 вне форума Ответить с цитированием
Старый 30.10.2009, 11:33   #7
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

замена сдвига на
Код:
          
rcr eax,1
вообще нужно сначала складывать весь массив, а потом сдвиг тоже всего массива,.
проверьте пример такой на своей программе
Код:
unsigned int a[5] = {1, 0, 0xfffffffe, 0xffffffff, 0xffffffff};
unsigned int b[5] = {1, 0, 0, 0, 1};
unsigned int c[5] = {0, 0, 0, 0, 0};
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru

Последний раз редактировалось airyashov; 30.10.2009 в 11:37.
airyashov вне форума Ответить с цитированием
Старый 30.10.2009, 13:14   #8
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

rcr как раз выдает то что надо, спасибо. Только вознкла еще одна проблемка

unsigned int a3[5] = {1, 0, 0xffffffff, 0xffffffff, 0xffffffff};
unsigned int b3[5] = {1, 0, 0, 0, 1};
unsigned int c3[5] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

поидее должен выдать

1
0
80000000
80000000
80000000

но получается так

1
0
80000000
7ffffffff
80000000

массив складывается с конца, тоесть при первом сложении флаг кери должен установиться в 1 т.к переполнение в 0xffffffff+1
след следующий элемент(c[4]) должен быть
0xfffffffff+1 >> 1 = 0x80000000
NiCola999 вне форума Ответить с цитированием
Старый 30.10.2009, 13:41   #9
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

вообще-то rcr изменит флаг CF после себя. Надо бы его как-нибудь обратно вернуть
Можно, для примера, после него поставить bt eax,31. Т.е. если после rcr старший бит в eax = 1, то она установит CF.

Вот только я что-то не очень понимаю. Вы считаете среднее арифметическое чисел a и b или отдельных чисел массивов ? И какое значение имеет начальное состояние c3?
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4

Последний раз редактировалось Goodwin98; 30.10.2009 в 13:45.
Goodwin98 вне форума Ответить с цитированием
Старый 30.10.2009, 14:00   #10
NiCola999
Не
Участник клуба
 
Регистрация: 29.10.2009
Сообщений: 1,456
По умолчанию

Цитата:
Вот только я что-то не очень понимаю. Вы считаете среднее арифметическое чисел a и b или отдельных чисел массивов ? И какое значение имеет начальное состояние c3?
a и b это как бы два длинных числа которые разбиты на части
например число 2^96
a = {2^32,2^32,2^32}

а какая разница какое состояние c3, я же туда записываю ответ, перетираю старые значения элементов
вообще
c3 = {0,0,0,0,0}

спасибо за bt, всё правильно теперь
вопрос пока снят, посмотрим к чему еще придерется препод =)

Последний раз редактировалось NiCola999; 30.10.2009 в 14:08.
NiCola999 вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
поменять большие буквы на маленькие и маленькие на большие в си++ Барби Помощь студентам 4 08.04.2008 01:25
csv-файл большие числа nevadimka Microsoft Office Excel 1 14.03.2008 10:25
Большие числа Лубышев Помощь студентам 6 27.02.2008 22:57
Большие комплексные числа xoz Общие вопросы Delphi 0 24.02.2008 03:12