Консультация № 185720
31.03.2012, 01:56
76.16 руб.
0 6 1
Здравствуйте, уважаемые эксперты! Прошу вас написать программу вот с таким заданием:

Дано 32-битное слово, поменять местами 15 и 16 биты.

Как она будет выглядеть в программе, я не понимаю, так что помогите решить, желательно к каждой строке комментарии.

п.с.
Ассемблер : TASM
Размер переменных: двойное слово
32-битные регистры используем.
Число прописываем сами в файле asm

Заранее спасибо.

Обсуждение

давно
Мастер-Эксперт
27822
2370
31.03.2012, 12:08
общий
31.03.2012, 12:12
Поскольку значение бита - либо 0 либо 1, то, после изменения значения каждого из 2-х битов на противоположные, результат будет такой же, как при обмене местами. Это делается командой "исключающее или" со словом, содержащим единицы в позициях изменяемых битов и нули в остальных. К сожалению, на Ассемблере я работал очень давно, коды с тех пор поменялись, нынешних не знаю, так что конкретнее посоветовать не могу.
Неизвестный
31.03.2012, 15:27
общий
Если старшие 2 бита числа не равны 00 и не равны 11, то сделать операцию "исключающее или" (xor) двух старших бит числа с 11.
давно
Посетитель
7438
7205
31.03.2012, 19:47
общий
15 и 16 биты - это считаем откуда? С 0 или 1? Т.е., считаем самый младший бит нулевым или первым?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
31.03.2012, 20:29
общий
это ответ
Здравствуйте, Yankov Dmitry!
Программа сделана универсально, может менять местами любые два бита
Кроме того, сделана из расчета, что биты считаются с 0,
Т.е., меняя биты 15 и 16, мы поменяем местами старший бит младшего слова
и младший бит старшего.
Если Вы считаете биты с единицы, т.е. нужно поменять местами два старших бита
младшего слова, то поменяйте в программе номера бит на 14 и 15
Удачи в понимании ассемблера!

Код:

.model small
.data
num dd 00000000000000001101010110101010b

.code
.386
start:
mov ax, @data
mov ds, ax

mov eax, num ;наше число
mov cl, 15 ;номер первого бита (счет с 0)
mov ch, 16 ;номер второго бита (счет с 0)
call ChangeBits ;меняем биты в eax
mov num, eax ;сохраняем результат

mov ax, 4c00h
int 21h

;меняем местами два бита врегистре eax,
;номера бит заданы в cl и ch
ChangeBits proc
;сформируем маску первого бита
mov edx, 1 ;поставим 1 в нужную позицию
shl edx, cl ;номер бита будет число, на которое надо сдвинуть
;сформируем маску второго бита
mov cl, ch ;его номер
mov ebx, 1
shl ebx, cl ;маска бита в ebx
;сформируем общую маску двух бит
or edx, ebx

;проверим, какие биты на указанных местах
mov ecx, eax ;наше число
and ecx, edx ;оставляем только нужные биты
jz CBret ;если оба нуля, то менять местами не надо
cmp ecx, edx ;если равны маске, значит оба единицы,
jz CBret ;также не меняем
xor eax, edx ;если разные, то операцией xor с единицами меняем местами
CBret:
ret
ChangeBits endp

end start

5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
31.03.2012, 21:01
общий
Если есть желание "поиграться" битами, могу предложить
еще одну подпрограмму обмена бит, но она меняем места
только младший бит старшего слова и старший бит младшего слова!
Все действие отражено в комментарии, где буковками отмечено следующее:
w - остальные биты старшего слова
x - младший бит старшего слова
y - старший бит младшего слова
z - остальные биты младшего слова
_ - неважное состояние
через запятую, в конце, значение флага С
Код:

cb proc ;wwwwwwwx yzzzzzzz,_
shl ax, 1 ;wwwwwwwx zzzzzzz_,y
rcl dl, 1 ;_______y,_
rol eax, 16 ;zzzzzzz_ wwwwwwwx,_
shr ax, 1 ;zzzzzzz_ _wwwwwww,x
rcr dl, 1 ;x_______,y
rcl ax, 1 ;zzzzzzz_ wwwwwwwy,_
rol eax, 16 ;wwwwwwwy zzzzzzz_,_
shl dl, 1 ;________,x
rcr ax, 1 ;wwwwwwwy xzzzzzzz,_
ret
cb endp

Удачи в разборе!
Но это частный случай и для понимания достаточно сложный,
но полезный для понимания работы с битами :)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
31.03.2012, 21:27
общий
Еще один подход в решении задачи
Тоже универсальная подпрограмма, номера бит в cl и ch
Идея такая: чтобы поменять бит, задаем две маски,
одну для того, чтобы сбросить старое значение бита, применяя операцию AND,
вторую - чтобы вставить новое значение, применяя маску OR
Т.о., зная номера бит, строим четыре маски и... получаем результат
Код:
;меняем местами два бита в регистре eax, 
;номера бит заданы в cl и ch
cb1 proc
;задаем маску очистки по and для первого бита
mov esi, 1
shl esi, cl ;1 в нужной позиции
not esi ;0 в нужной позиции

;сформируем маску установки по or для второго бита
mov edx, eax ;наше число
shr edx, cl ;первый бит стал, как нулевой
and edx, 1 ;оставляем только 0 бит
xchg cl, ch ;и вдвигаем его на позицию второго
shl edx, cl ;в edx на позиции второго бита бывший первый

;задаем маску очистки по and для второго бита
;в cl позиция второго
mov edi, 1
shl edi, cl ;1 в нужной позиции
not edi ;0 в нужной позиции

;сформируем маску установки по or для первого бита
mov ebx, eax ;наше число
shr ebx, cl ;второй бит стал, как нулевой
and ebx, 1 ;оставляем только 0 бит
xchg cl, ch ;и вдвигаем его на позицию первого
shl ebx, cl ;в ebx на позиции первого бита бывший второй

;маски сформированы, подправим число
and eax, esi ;сбросим первый бит
and eax, edi ;сбросим второй бит
or eax, edx ;вставим первый на место второго
or eax, ebx ;вставим второй на место первого
ret
cb1 endp

Удачи!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа