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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.01.2012, 14:13   #1
NORDOM
Новичок
Джуниор
 
Регистрация: 20.01.2012
Сообщений: 2
По умолчанию Ассемблер.Поразрядная обработка.

Доброго времени суток! Прошу вашей помощи в написании одной простой программы. В данный момент я пишу крупную программу на паскале и пока что нет времени разбираться с новым для меня языком.

Собственно суть задания -
"Определить положение младшей единицы в числе x"

Буду рад любой помощи.
NORDOM вне форума Ответить с цитированием
Старый 20.01.2012, 14:40   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

проверяете число X на равенство нулю - если равно выход, что единицы нет.
если же число не равно нуляю, тогда загружаете число X в регистр и двигаете его циклически вправо, каждый раз проверяя крайний правый разряд (выход, когда крайний правый разряд равен 1), так же в этом цикле наращивайте счётчик.
при выходе из цикла значение счётчика и даст положение младшей единицы в числе X (при нумерации разрядов справа налево, разумеется)!


p.s. ассемблеры - они разные бывают. Всегда указывайте под какой именно Вам нужно решение...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 20.01.2012, 22:24   #3
NORDOM
Новичок
Джуниор
 
Регистрация: 20.01.2012
Сообщений: 2
По умолчанию

Okay. Использую FASM ассемблер.
значит части задачи:
-получаем некоторым образом двоичное(или любое?) число х;
-сравниваем x с 0 , если равно - выход;
-загружаем число х в регистр ;
-начинается цикл
увеличиваем счетчик на 1;
двигаем х вправо ,который в регистре;
сравниваем крайний правый разряд с 1;
выход если разряд равен 1;
-конец цикла.
-вывод на экран значения счетчика.

Из хаотичного изучения учебников, документаций и исходников я узнал такие вещи :
x dd 01101 ; помещает в переменную х значение 01101000(или любое другое)
MOV EAX, x ; помещает значение переменной х в регистр EAX
CMP EAX,EBX ; сравнивает 2 регистра. То есть нужно EBX предварительно
приравнять к нулю. Я уверен есть более правильный способ сравнить значение переменной с 0. Только какой?
je label; если EAX равен 0 то переходим к метке label. Эта метка будет где то в конце программы и после нее идет строчка:
invoke ExitProcess,0

Далее каким то неизвестным мне способом организовываем цикл.Как его сделать?

inc i; увеличивает на 1 значение i (естественно предварительно обнуленной). Можно тут использовать переменную или нужно использовать регистр?

shl EAX,1 ; сдвигает регистр влево на 1 бит.А как сдвинуть вправо?

CMP EAX, EBX ; теперь сравниваем крайний правый разряд с 1. Как узнать значение крайнего правого разряда?
je label_2 ; если они равны переходим к выводу результатов.

mov ax,i ; записываем в регистр ах значение счетчика
out 20h,ax ; примерно так выводим значение на экран.То есть я догадываюсь что совсем не так.Или вывод результатов не нужен при такой постановке задачи?
Вообщем до вывода еще далеко, хотелось бы узнать ваше мнение и советы по остальным частям программы.
NORDOM вне форума Ответить с цитированием
Старый 21.01.2012, 10:26   #4
8Observer8
Старожил
 
Регистрация: 02.01.2011
Сообщений: 3,328
По умолчанию

FASM, к сожалению, не изучал, а на МASM'e, так:
Код:
.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc

includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib

BSIZE       equ    128

.data     
ifmt        db     "%d",0
buf         db     BSIZE dup(?)
stdout      dd     ?
cWritten    dd     ?
x           dd     01101000b
counter     dd     0

.code
start:
    ; проверяем входное значение на равенство нулю
    mov eax, x
    cmp eax, 0     ; обычно обнуляют так: xor ebx, ebx, в данном случае лучше явно ноль написать
    jz exit

next:
    shr eax, 1     ; при сдвиге выдвинутая единица сохраняется в бите carry
    inc counter
    jnc next       ; если бит carry равен единице, то выводим результат

    ; выводим результат на экран
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov stdout, eax
    dec counter    ; нумерация битов с нуля
    invoke  wsprintf, ADDR buf, ADDR ifmt, counter
    invoke WriteConsole, stdout, ADDR buf, \
           BSIZE, ADDR cWritten, NULL

exit:
    invoke ExitProcess, 0
end start
P.S. Советую скачать книгу Крупника "Изучаем ассемблер". Она маленькая и там есть всё, что нужно для прикладных задач. Автор подробно рассказывает, как пользоваться отладчиком OllyDbg. Примеры кода, OllyDbg, можно скачать с сайта питера (посмотрите в начале книги, автор пишет, где и что можно достать)

Последний раз редактировалось 8Observer8; 21.01.2012 в 16:49. Причина: убрал ненужный комментарий в строке: mov eax, x
8Observer8 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ассемблер farxad Помощь студентам 6 11.09.2016 14:19
Поразрядная обработка целых чисел(declaration si now allowed here) Nice Plant Помощь студентам 0 24.10.2010 21:43
Ассемблер VD1988 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 20.05.2010 22:10
Ассемблер, обработка цепочек символов <Yuliya> Помощь студентам 0 20.01.2010 18:55
Поразрядная сортировка беззнаковых целых чисел горе-программист Помощь студентам 0 12.04.2009 02:20