Обратный байт с использованием ассемблера - PullRequest
7 голосов
/ 07 февраля 2011

Я нахожусь в классе микропроцессоров, и мы используем ассемблер в Freescale CodeWarrior для программирования микроконтроллера 68HCS12.Наше назначение на этой неделе состоит в обращении байта, поэтому, если бы байт был 00000001, выходной результат был бы 10000000 или от 00101011 до 11010100. Мы должны использовать язык ассемблера, и нам сказали, что мы можем использовать вращения и сдвиги (но не ограничиваясь!) выполнить эту задачу.Я действительно в растерянности относительно того, с чего мне начать.

Ответы [ 8 ]

8 голосов
/ 07 февраля 2011

Подсказки: если вы делаете сдвиг, один бит сдвигается, и ноль (вероятно) сдвигается внутрь. Куда идет этот сдвинутый бит? Вам нужно переместить это на другой конец регистра назначения или адреса памяти.

Я уверен, что 25 лет назад я мог сделать это в машинном коде Z80 без ассемблера:)

7 голосов
/ 07 февраля 2011

Рассмотрим два регистра как стеки битов. Что произойдет, если вы будете переходить по одному биту от одного к другому?

6 голосов
/ 07 февраля 2011

Если вы можете сэкономить дополнительный размер кода в 256 байтов, таблица поиска, вероятно, является наиболее эффективным способом обращения байта в 68HCS12. Но я почти уверен, что это не то, чего ожидает твой инструктор.

Для «нормального» решения учитывайте биты данных по отдельности. Вращения и сдвиги позволяют вам перемещать биты вокруг. Для первого решения выделите восемь битов (с помощью побитовых операций «и»), переместите их в их целевые позиции (сдвиги, вращения ...), затем снова объедините их вместе (с помощью побитовых операций «или»). Это будет не самая эффективная или самая простая реализация, но сначала вы должны сосредоточиться на получении правильного результата - оптимизация может подождать.

3 голосов
/ 21 ноября 2017

Например, если у вас есть в байтовом номере самый простой способ:

mov al, 10101110
mov ecx, 8

, мы помещаем 8 в ecx для цикла

mov ebx, 0 

В bl мы получим результат, мы сделаем ebx, только чтобы посмотреть, что получится лучше

loop1:
sal al, 1;           

В флаге переноса теперь у вас есть последний бит слева

rcr bl, 1;           

, теперь вы добавляете в bl то, что имеетенести

loop loop1

и это все

3 голосов
/ 07 февраля 2011

Когда вы делаете правильный сдвиг, младший бит попадает в флаг переноса.

Когда вы делаете поворот, флаг переноса используется для заполнения освобожденного бита результата (LSB для ROL, MSB для ROR).

3 голосов
/ 07 февраля 2011

Прежде всего, разработайте алгоритм для выполнения того, что вам нужно. Выразите это в виде псевдокода, или C, или простого английского языка, или диаграмм, или того, что вам удобно. После устранения этого концептуального барьера фактическая реализация должна быть довольно простой.

Ваш CPU, вероятно, имеет инструкции, которые позволяют вам сдвигать и / или вращать регистр, возможно, включая флаг переноса в качестве дополнительного бита. Эти инструкции будут очень полезны.

1 голос
/ 09 февраля 2011

Это был комментарий, но я подумал WTH!

Для экономии места над 256-байтовой таблицей у вас может быть 16-байтовая таблица, содержащая значения для четырех битов (кусков) за раз. Алгоритм тогда будет

revval=(revdigit[inval&0x0f]<<4)|
        revdigit[inval>>4];

Если бы я был профессором, я бы, конечно, хотел бы две части, где одна смена находится в индексировании, а другая снаружи.

0 голосов
/ 03 апреля 2015

Мне также пришлось запрограммировать этот бит в обратном порядке для университета (для 8 бит). Вот как я это сделал:

MOV AL, 10001011B ;set the value to test
MOV CL, 7
MOV DH, 1
MOV DL, 0

loop1: PUSH AX
AND AL, DH 
PUSH CX
MOV CL, DL
SHR AL, CL
POP CX
MOV BH, AL
SHL BH,CL
OR CH,BH
DEC CL
INC DL
SHL DH, 1
POP AX
CMP DL, 8
JE END
JMP LOOP1

END:

Я не прокомментировал это, вот как это работает: DH - это 1, который перемещается в байте, как в первый раз: 00000001; второй раз 00000010 и так далее. Когда вы делаете AND с AL, вы получаете 0 или что-то вроде 100 или 10000, вам нужно сдвинуть его вправо, чтобы получить 0 или 1. Затем поместите его в ЧД и переместите в нужную позицию, которая равна 7 для байта 0, 6 для байта 1 и так далее. Затем OR до нашего окончательного результата и INC и DEC, что необходимо. Не забудьте условные переходы и выведите AX для следующего цикла:)

Результат будет в канале.

...