Из этой темы http://kazus.ru/forums/showthread.php?t=8950&page=2, я к сожалению мало что понял...
Буду очень рад помощи!
Спасибо!
Так ведь пример-то все равно придется соотносить с теорией, чтобы не вслепую писать. Скажем, для 24 бит выйдет что-то типа такого:czuryk писал(а):Не у кого нет готового решения реализации на ASM...
Код: Выделить всё
.DSEG
; Store SEED value here -
_random_b1: .BYTE 0x1
_random_b2: .BYTE 0x1
_random_b3: .BYTE 0x1
.CSEG
rand:
clr r15 ; accumulator/flag
lds r30,_random_b1
sbrc r30,0x02; check for 1-st tap
inc r15 ; note if found 1
lds r30,_random_b2
sbrc r30,0x00; check for 2-nd tap
inc r15 ; note if found 1
sbrc r30,0x06; check for 3-rd tap
inc r15 ; note if found 1
lds r30,_random_b3
sbrc r30,0x07; check for 4-th tap
inc r15 ; note if found 1
clc
sbrc r15,0x00
sec
; Shift right through Carry - C > B3 > C > B2 > C > B1
ror r30 ; already contains (_random_)B3
sts _random_b3,r30 ; save it
lds r30,_random_b2 ; get B2
ror r30 ; ...
sts _random_b2,r30
lds r30,_random_b1
ror r30
sts _random_b1,r30 ; now R30 contains RetVal (random)
retКод: Выделить всё
.include "tn2313def.inc"
.list
.def temp = R16
.def work = R17
.equ kdel2 = 0x30
//.equ kdel2 = 0xFF
.dseg ; Выбираем сегмент ОЗУ
.org 0x60 ; Устанавливаем текущий адрес сегмента
buf: .byte 1
_random_b1: .BYTE 0x1
_random_b2: .BYTE 0x1
_random_b3: .BYTE 0x1
; ---------- Начало програмного кода
.cseg ; Выбор сегмента программного кода
.org 0 ; Установка текущего адреса в ноль
; ---------- Переопределение векторов прерываний
start:
rjmp init ; Переход в начало программы
reti ; Внешнее прерывание 0
reti ; Внешнее прерывание 1
reti ; Таймер/счетчик 1, захват
reti ; Таймер/счетчик 1, совпадение, канал A
reti ; Таймер/счетчик 1, прерывание по переполнению
reti ; Таймер/счетчик 0, прерывание по переполнению
reti ; Прерывание UART прием завершен
reti ; Прерывание UART регистр данных пуст
reti ; Прерывание UART передача завершена
reti ; Прерывание по компаратору
reti ; Прерывание по изменению на любом контакте
reti ; Таймер/счетчик 1, совпадение, Канал B
rjmp tim0 ; Таймер/счетчик 0, совпадение, Канал B
reti ; Таймер/счетчик 1, совпадение, Канал A
reti ; USI готовность к старту
reti ; USI переполнение
reti ; EEPROM Готовность
reti ; Переполнение охранного таймера
; ---------- Модуль инициализации
init:
; ---------- Инициализация стека
ldi temp, RAMEND; Выбор адреса вершины стека
out SPL, temp ; Запись его в регистр стека
; ---------- Инициализация портов BB
// ldi temp, 0 ; Записываем ноль в регистр temp
ldi temp, 0xFF ; Записываем число $FF в регистр temp
out DDRD, temp ; Записываем этот ноль во DDRD (порт PD на ввод)
ldi temp, 0xFF ; Записываем число $FF в регистр temp
out DDRB, temp ; Записываем temp в DDRB (порт PB на вывод)
ldi temp, 0xFF ; Записываем число $FF в регистр temp
out DDRA, temp ; Записываем temp в DDRA (порт PA на вывод)
out PORTB, temp ; Записываем temp в PORTB (потушить светодиод)
out PORTD, temp ; Записываем temp в PORTD (включаем внутренний резистор)
out PORTA, temp ; Записываем temp в PORTD (включаем внутренний резистор)
; ---------- Инициализация таймера T0
// ldi temp, 0x0D ; Код конфигурации записываем в temp
ldi temp, 0x01 ; Код конфигурации записываем в temp
out TCCR0B, temp ; Переносим его в регистр конфигурации таймера
ldi temp, kdel2;
out OCR0A, temp ;
; --------- Определение маски прерываний
ldi temp, 0b01000001; Байт маски. Разрешено одно прерывание (№4)
out TIMSK, temp ; Записываем маску
; ---------- Инициализация компаратора
ldi temp, 0x80 ; Выключение компаратора
out ACSR, temp
; ---------- Начало основного цикла
main:
sei ; Разрешение прерываний
m1:
rjmp m1 ; Пустой бесконечный цикл
; =====================
; Программа обработки прерываний
; =====================
tim0:
push temp ; Сохраняем регистр temp
rcall rand
lds temp, _random_b3 ;
out PORTB, temp
ldi temp, 0 ; Младший полубайт кода совпадения
out TCNT0, temp ;
pop temp ; Восстановление регистра temp
reti
rand:
push temp ; Сохраняем регистр temp
push work ; Сохраняем регистр temp
clr temp ; очищаем r15
lds work, _random_b1 ; Загружаем в r30 содержимое ячейки памяти _random_b1
sbrc work, 0x02 ; Пропуск следующей комманды, если 1-й бит = "0"
inc temp ; Увеличиваем r15
lds work, _random_b2 ; Загружаем в r30 содержимое ячейки памяти _random_b2
sbrc work, 0x00 ; Пропуск следующей комманды, если 0-й бит = "0"
inc temp ; Увеличиваем r15
sbrc work, 0x06 ; Пропуск следующей комманды, если 6-й бит = "0"
inc temp ; Увеличиваем r15
lds work, _random_b3 ; Загружаем в r30 содержимое ячейки памяти _random_b3
sbrc work, 0x07 ; Пропуск следующей комманды, если 7-й бит = "0"
inc temp ; Увеличиваем r15
clc ; Очищаем флаг "С"
sbrc temp, 0x00 ; Если r15 четное:
sec ; Устанавливаем флаг "C"
; Shift right through Carry - C > B3 > C > B2 > C > B1
ror work ; Циклический сдвиг содержимого регистра вправо. 7-й разряд переходит в C
sts _random_b3, work ; Сохраняем r30 в ячейки памяти _random_b3
lds work, _random_b2 ; Загружаем в r30 содержимое ячейки памяти _random_b2
ror work ; Циклический сдвиг содержимого регистра вправо. 7-й разряд переходит в C
sts _random_b2, work ; Сохраняем r30 в ячейки памяти _random_b2
lds work, _random_b1 ; Загружаем в r30 содержимое ячейки памяти _random_b1
ror work ; Циклический сдвиг содержимого регистра вправо. 7-й разряд переходит в C
sts _random_b1, work ; Сохраняем r30 в ячейки памяти _random_b1
lds r20, _random_b1 ;
lds r21, _random_b2 ;
lds r22, _random_b3 ;
pop work ; Восстановление регистра temp
pop temp ; Восстановление регистра temp
ret
А может ты просто не умеешь их готовить?czuryk писал(а):При подстановки начальных значений - вообще не работает, без низ работает, но как оказалось - совсем не так как мне надо. Легко просматривается циклический сдвиг. Никакой случайности!

Код: Выделить всё
push temp ; Сохраняем регистр temp
rnd_repeat: ; Выполняем 3 полных байтовых сдвига
rcall rand
inc rndcnt
cpi rndcnt, 24
brlt rnd_repeat
ldi rndcnt, 0
lds temp, _random_b3 ;
out PORTB, temp
ldi temp, 0 ;
out TCNT1H, temp ; Обнуляем TIMER1
out TCNT1L, temp ; Обнуляем TIMER1
pop temp ; Восстановление регистра temp
reti
Ну, что ж, и слава богу. Вот только, я вижу - ты так и оставил тот код, который я накропал исключительно в иллюстративных целях... ну, ладно, раз читать лениво, то...czuryk писал(а):...и проблема решена.
Ну, это как раз самое простое; feedback - обратная связь, то есть тот метод, который читает значения из заданных разрядов и формирует из них следующий бит, подаваемый в регистр, а TAP - это, в данном случае, один из используемых разрядов. Где написано "24 bits, 4 taps" - читаем "всего разрядов - 24, из них 4 используются для формирования нового бита (ОС)".czuryk писал(а):...поясни что значит TAP и Feedback ...
http://rain.ifmo.ru/cat/view.php/theory ... 005/streamczuryk писал(а): На русском я так материалов и не нашел.
чем меньше длина регистра, тем быстрее начнутся повторенияczuryk писал(а):А код подправлять я не вижу особого смысла - пробовал только упрощать снижая количество регистров до 1-го, но получилось не очень.
да, в некоторые термины сложно выникнуть непосвященным... у меня в свое время пару часов ушло чтоб вникнуть во всю эту кухню с регистрами...на самом деле все просто...на примере одного регистра (8 бит), так как тебе не знакома криптография, то выбираешь с потолка номера битов, пусть будет первый и шестой - это и будут твои TAP - точки съема. Согласно вашего примера, если в каждом из выбранных ТАРах стоит единица, то инкрементируется счетчик. Т.е. результатом одного сдвига есть сумма выбранных тобой ТАРов, тобишь первого и шестого бита. И от этой суммы зависит будет ли установлен флаг переноса или нет, который потом пойдет обратно в 7 бит регистра. Т.е. получается уже целая функция - это и есть Feedback, дословно - функция с обратной связью. Т.е. у тебя есть обратная связь с тем, что выходит из регистра и результатом возвращается в начало.czuryk писал(а): P/S Но если тебе не трудно, поясни что значит TAP и Feedback functions из мана мне ее описание показалось очень туманным.