LINUX.ORG.RU

MSP430. Вопрос к тем кто работал с PDP-11. Программирование машинными кодами. Поделитесь опытом.

 , ,


0

2

В руки попал микроконтроллер MSP430 с платой LaunchPad. Искал какие есть инструменты для программирования и прошивки. В составе MSPFlasher попался файл Firmware.txt следующего содержания:

@e000
21 83 B2 40 80 5A 20 01 F2 D3 22 00 F2 E3 21 00 
B1 40 10 27 00 00 91 83 00 00 81 93 00 00 FB 23 
F5 3F 31 40 00 04 B2 40 48 E0 00 02 B2 40 48 E0 
02 02 B0 12 40 E0 0C 43 B0 12 00 E0 B0 12 44 E0 
1C 43 30 41 03 43 FF 3F 30 41 
@fffe
22 E0 
q

С помощью другой программы mspdebug у меня получилось зашить этот Firmware.txt:

$ ./mspdebug rf2500
(mspdebug) erase
Erasing...
(mspdebug) load ../MSPFlasher_1.3.20/Firmware.txt 
Done, 76 bytes total
(mspdebug) exit

После этого светодиодики бодро заморгали на плате.

Мне захотелось тоже попробовать хоть что-нибудь написать таким образом, просто чтобы был такой опыт. Если верить википедии, у MSP430 схожая система команд с PDP-11. Я относительно молодой, PDP-11 совсем не застал.

Здесь на форуме от разных людей видел комментарии в духе «дайте мне в руки PDP-11 и я вспомню как это делается». В руки, увы, ни PDP-11, ни MSP430 не дам. Но если поделитесь опытом, буду очень рад!

Вот, что, к примеру, делает программа описанная в файле Firmware.txt? Я, например, пока не могу расшифровать. :^)

Мне захотелось тоже попробовать хоть что-нибудь написать таким образом, просто чтобы был такой опыт.

Тогда можно просто сходить на интернет-страницу производителя твоего микроконтроллера и скачать среду разработки и описание системы команд микроконтроллера оттуда.

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

Enthusiast ★★★☆
()
Ответ на: комментарий от Enthusiast

и скачать среду разработки

По максимуму стараюсь не использовать любые IDE. Меня крокодил покусал.

описание системы команд микроконтроллера оттуда

Да, описание есть.

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

Мне просто для опыта. :^)

Jullyfish
() автор топика
Ответ на: комментарий от pfg

у мсп430 хорошая документация на сайте техаса и куча исходников. iar и т.д.

Не спорю, хотя инструменты явно делались под форточки, что крайне неприятно. А сами машинные команды и в обычной википедии написаны. Мне скорее помощь в этом разобраться.

Как я понимаю @e000 адрес куда записывается программа. Далее команда 0x23 = 0010_0011, что она делает, пока не получается разобраться.

Jullyfish
() автор топика

MSP430

Не, ставь Code Composer и пиши на Си. А PDP-11 для уюта, тетриса и винтажа нужен.

форточки

У тексаса под прошлую Ubuntu LTS есть.

А, коды PDP-11 - можно поискать сканы журналов 80-х с листингами восьмеричных кодов для БК-0010. Иногда забавно было.

Shadow ★★★★★
()
Последнее исправление: Shadow (всего исправлений: 3)

На MSP430 отличная документация у TI.

На PDP-11 он действительно чем-то похож. Есть масса отечественной литературы по системе команд и программированию 1801ВМ1, который являлся советским однокристальным микропроцессором с системой команд PDP-11. Был очень популярен в качестве embedded процессора во всяких промышленных контроллерах, использовался в массовых ДВК, БК0010 и MK85, так что русскоязычной литературы по нему море. Общее представление и принципы можно оттуда почерпнуть, но без документации TI на MSP430 всё равно никак не обойтись - процессоры и система команд всё-же разные, хоть и похожи, ну и периферия одеокристалок MSP430 разумеется не описана в книгах про 1801ВМ1/PDP-11.

Stanson ★★★★★
()

схожая система команд с PDP-11

Схожая идеологически, по факту вообще другая и не совместимая. Забудь про pdp-11, ищи мануалы конкретно для MSP430.

no-such-file ★★★★★
()

Похоже надо смотреть по 2 байта.

0x21 0x83 это 0010_0001_1000_0011.

Если верить Википедии, 0010_00 это jnz, а оставшиеся 01_1000_011 – смещение. Но как-то странно, смещение > 256, а программа 76 bytes total.

Jullyfish
() автор топика

Отсюда:

@ADDR1
DATA01 DATA02 ........ DATA16
DATA17 DATA18 ........ DATA32
........
DATAm ........ DATAn
@ADDR2
DATA01 ........ DATAn
q

Where:

@ADDR is the start address of a section (hexadecimal).
DATAn represents a data byte (hexadecimal).
q is the termination of the file.

For example:

@F000
31 40 00 03 B2 40 80 5A 20 01 D2 D3 22 00 D2 E3
21 00 3F 40 E8 FD 1F 83 FE 23 F9 3F
@FFFE
00 F0
Q

Restrictions:
• The number of sections is unlimited.
• Each line can have a maximum of 16 data bytes, except the last line of a section.
• Data bytes are separated by a single space.
• The termination tag q indicates end-of-file is mandatory.
Jullyfish
() автор топика

Прелесть программирования PDP-11 (и MSP430) - в ортогональности её системы команд. Почти любую операцию можно выполнить почти с любыми операндами, используя единый набор способов адресации. Ну и всякие плюшки типа автоинкремента/автодекремента. Это не значит, что нужно составлять программу в виде текстового файла. Это значит, что удобно программировать на ассемблере.

Beewek ★★★★
()
Ответ на: комментарий от Beewek

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

Как я слышал, что прелесть PDP-11, что как раз удобно машинными командами программировать. А потом придумали RISC, ибо зачем делать «удобные и красивые» машинные команды, если есть мнемоники.

Возможно заблуждаюсь.

Jullyfish
() автор топика
Ответ на: комментарий от Jullyfish

Возможно заблуждаюсь.

Тут зависит от того, что тебе нужно. Если ты хочешь потренировать память, запоминая опкоды команд, то продолжай. А если хочешь оценить красоту системы команд - то тут всё же нужен ассемблер. Или даже компилятор си и дизассемблер. Там более наглядно видно, как красиво ложатся сишные конструкции на ассемблерные инструкции.

Beewek ★★★★
()

Машинные коды для PDP-11 нужно смотреть в восьмеричной форме. Там почти все по 3 бита кодируют. 8 регистров, 8 способов адресации.

vel ★★★★★
()

Привет! я много писал в машкодах на БК0010-01. Так вот, надо не 16ричный а восьмеричный подход использовать, тогда запоминается моментом.

12700 - mov r0, r0 12701 - mov r0, r1 00240 - nop

и тд

chumpa
()
Ответ на: комментарий от chumpa

Если я правильно понял, надо брать по два байта и читать справа-налево.

Т.е. 0x83 0x21 это 1000_0011 0010_0001, а это 0203 0041.

Первый байт:1000_ это sub (как-то не вписывается в восмеричное, ну ладно), _0011 это R3.

Второй байт 0010_:

  • 0 - это регистр;
  • 0 - значит байт;
  • 10 - косвенная адресация без инкремента (тут гнетут сомнения).

_0001 и это всё идёт в R1.

Что-то вроде sub.b [r3] r1 получается?

Jullyfish
() автор топика

Я относительно молодой, PDP-11 совсем не застал.

Здесь на форуме от разных людей видел комментарии в духе «дайте мне в руки PDP-11 и я вспомню как это делается». В руки, увы, ни PDP-11, ни MSP430 не дам. Но если поделитесь опытом, буду очень рад!

Вот, что, к примеру, делает программа описанная в файле Firmware.txt? Я, например, пока не могу расшифровать. :^)

Если это действительно PDP-11, то вам надо поискать документацию к компбютеру отечественному, УКНЦ. Я не помню, на каком чипе он сделан. Довольно точная копия, даже адреса регистров совпадали (что позволяло использовать код написанный для PDP11).

В интернете видел ассемблер для УКНЦ.

И да, если это действительно PDP-11, то там нативно - восьмеричная система используется :). Опкоды удобнее читать, когда они восьмерично записаны - там, типа, номера регистров видно по дампу. Но я уже не вспомню цифр конкретных.

vvb333007
()
Ответ на: комментарий от Jullyfish

2 байта 0x8321 это 1 слово 101441 MOVB (r4),-(r1)

Очень странно. Это точно не начало прошивки.

@e000 - начало прошивки в @FFFE занесли 0xE022 - адрес старта?

В 94 году у меня был самописный эмулятор pdp-11 (без MMU) который работал даже на ХТ.

vel ★★★★★
()
Ответ на: комментарий от vel

Очень странно. Это точно не начало прошивки.

(mspdebug) dis 0xfffe
0xfffe:
    0fffe: 22 e0                     XOR     @PC,    SR

@PC, как я понимаю значение Program Counter. А вот что такое SR, не знаю. Если вместо этого записать 0xff 0xff, ругается:

(mspdebug) run
fet: FET returned error code 17 (Could not run device (to breakpoint))
fet: failed to restart CPU
run: failed to start CPU

На форуме ti пишут, что по адресу 0xfffe CUSTOM_RESET.

@e000 - начало прошивки в @FFFE занесли 0xE022 - адрес старта?

Очень похоже.

В 94 году у меня был самописный эмулятор pdp-11 (без MMU) который работал даже на ХТ.

А я в то время ещё не родился. И что такое XT – не знаю.

Jullyfish
() автор топика
Ответ на: комментарий от Jullyfish

Там всего 8 регистров R0-R5, R6 / SP (Stack Pointer), R7 / PC.

В микроконтроллерах MSP430 по адресу 0xFFFE находится вектор сброса (Reset Vector). Это самое важное слово в памяти программ, так как именно отсюда микроконтроллер узнает, с какого адреса начинать выполнение программы после подачи питания или аппаратного сброса.

У тебя прошивка загружается с 0xE000, а старт происходит с 0xE022
31 40 00 04
40061 0400 «BIC R0,2000(R1)» - вполне разумная команда. Только нужно узнать что находится в регистрах после сброса.

https://en.wikipedia.org/wiki/PDP-11_architecture

PS IBM PC XT (i8086 или i8088), IBM PC AT (i80286)

vel ★★★★★
()
Ответ на: комментарий от Morin

Машкоды это жесть

Ну когда я для 8080 писал, где-то половину знал наизусть. C3, C9 и CD помню до сих пор. Но да, это не PDP-11, это сильно другая ветвь эволюции (на мой тогдашний взгляд, более простая и логичная).

hobbit ★★★★★
()
E000: 21 83          SUB     #4, SP

E002: B2 40 80 5A
E006: 20 01          MOV     #0x5A80, &0x0120
                    ; WDTCTL = 0x5A80
                    ; WDTPW | WDTHOLD -> остановить watchdog

E008: F2 D3 22 00    BIS.B   #-1, &0x0022
                    ; P1DIR |= 0xFF
                    ; весь Port 1 -> output

E00C: F2 E3 21 00    XOR.B   #-1, &0x0021
                    ; P1OUT ^= 0xFF
                    ; инвертировать все выходы Port 1

E010: B1 40 10 27
E014: 00 00          MOV     #0x2710, 0(SP)
                    ; local_variable = 10000

E016: 91 83 00 00    SUB     #1, 0(SP)
                    ; --local_variable

E01A: 81 93 00 00    CMP     #0, 0(SP)

E01E: FB 23          JNZ     E016
                    ; while (local_variable != 0)

E020: F5 3F          JMP     E00C

Тут зачем-то вместо конкретного бита на котором висит светодиод хлопают весь байт.

https://www.ti.com/lit/ug/slau144/slau144.pdf

Раздел 3.4, instruction set, там же формат команд.

PPP328 ★★★★★
()
Ответ на: комментарий от Jullyfish

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

чето типа 01AaBb - mov Aa, Bb, где маленькие буквы - номер регистра, а большие - способ адресации

или 04+XX - br XX, относительный переход на XX

до сих пор помню

sergej ★★★★★
()
Последнее исправление: sergej (всего исправлений: 1)
Ответ на: комментарий от sergej

помню в детстве отдельно доставлял способ вытаскивания констант и адресов из следующего за командой слова как косвенная автоинкрементная адресация по регистру PC

и аналогичная работа со стеком командой mov с инкрементной/декрементной адресацией по регистру SP

sergej ★★★★★
()

Железо и не нужно. Интерпретатор машкодов напиши. Пишется на раз-два (сам однажды написал по юности), там простой ассемблер.

dimgel ★★★★★
()
Ответ на: комментарий от hobbit

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

Morin ★★★★★
()
Ответ на: комментарий от PPP328

А чем перегоняли в ассемблер?

Я пока относительно нормальный вариант нашёл, если прошить устройство, а потом посмотреть с помощью mspdebug.

E000: 21 83 SUB #4, SP

Вот это вызывает подозрение, что ИИшка. Она каждый раз по-разному переводит в ассемблер.

Jullyfish
() автор топика

Дизассемблированное с помощью mspdebug:

    0e000: 21 83                     DECD    SP
    0e002: b2 40 80 5a 20 01         MOV     #0x5a80, &0x0120
    0e008: f2 d3 22 00               BIS.B   #0xff,  &0x0022
    0e00c: f2 e3 21 00               INV.B   &0x0021
    0e010: b1 40 10 27 00 00         MOV     #0x2710, 0x0000(SP)
    0e016: 91 83 00 00               DEC     0x0000(SP)
    0e01a: 81 93 00 00               TST     0x0000(SP)
    0e01e: fb 23                     JNZ     0xe016
    0e020: f5 3f                     JMP     0xe00c
    0e022: 31 40 00 04               MOV     #0x0400, SP
    0e026: b2 40 48 e0 00 02         MOV     #0xe048, &0x0200
    0e02c: b2 40 48 e0 02 02         MOV     #0xe048, &0x0202
    0e032: b0 12 40 e0               CALL    #0xe040
    0e036: 0c 43                     CLR     R12
    0e038: b0 12 00 e0               CALL    #0xe000
    0e03c: b0 12 44 e0               CALL    #0xe044
    0e03c: b0 12 44 e0               CALL    #0xe044
    0e040: 1c 43                     MOV     #0x0001, R12
    0e042: 30 41                     RET     
    0e044: 03 43                     NOP     
    0e046: ff 3f                     JMP     0xe046
    0e048: 30 41                     RET
    ...
    0fffe: 22 e0                     XOR     @PC,    SR
Jullyfish
() автор топика
Ответ на: комментарий от PPP328

Тут зачем-то вместо конкретного бита на котором висит светодиод хлопают весь байт.

Потому что это программа мигания всеми ледами. И все линии P1 будут меняться.

ant1
()
Ответ на: комментарий от Jullyfish

Как я слышал, что прелесть PDP-11, что как раз удобно машинными командами программировать.

Батенька вы явно не понимаете (не теоретически а практически) разницу между машинными кодами и ассемблером. Так же явно путаете слово «удобно» и слово «удобнее чем». Программировать PDP-11 в машинных кодах было удобнее чем многие другие процессоры того времени. То что вам, дитю 2026 года, будет удобно в машкодах программировать PDP-11…. ah, sweet summer child.

Не будет удобно.

Если очень хотите научится ставьте соотв ассемблер и читайте получившийся код расшифровывая по документации на машинный.

anonymous
()
Ответ на: комментарий от Jullyfish

Помигай светодиодами:

void main(void)
{
    volatile unsigned int i;

    /* Остановить Watchdog Timer */
    WDTCTL = WDTPW | WDTHOLD;

    /* P1.0...P1.7 — выходы */
    P1DIR = 0xFF;

    while (true) {
        /* Инвертировать все линии порта P1 */
        P1OUT ^= 0xFF;

        /* Задержка */
        i = 10000;
        while (i--);
    }
}
ant1
()
Последнее исправление: ant1 (всего исправлений: 1)
Ответ на: комментарий от anonymous

В данном случае это неважно, т.к. там просто указан адрес, откуда начинается выполнение программы.

На самом деле довольно интересно. Если взять тот же atmega328p, там после reset счётчик команд равен 0 и принято по адресу 0 ставить jmp reset. А тут просто адрес без каких-либо команд.

Jullyfish
() автор топика

есть много разных ментал спортивных дисциплин https://wiki.c2.com/?MentalMasturbation

очевидно творчество не возможно без наличия ограничений и их творческого избегания

у того самого дяди Боба (Мартина) есть автобиографическая We Programmers как и Пола Алена

обычно в настоящей промышленности была кросс компиляция

либо раскрутка эталонный пример Чак Мур который фортил и фортил любое программируемое устровсто у которого есть хотябы четверть кило для repl

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

даже 1 кило это шикарные апартаменты

а уж 4 так ваще

читать шестрадцатиричные(а точнее восьмиричные) коды особенно на почти risc очень быстрый навык как жонглирование за 2-3 месяца активной практики

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

qulinxao3 ★☆
()
Ответ на: комментарий от Jullyfish

напиши свой декодер из бинаря в мнемоники(можешь себе удобные выбрать ежель ваще не желаешь ide и прочее коллективное)

опять же полиморфный код перестал быть хорошим тоном - как и готу внутрь тела процедуры

qulinxao3 ★☆
()
Ответ на: комментарий от Jullyfish

начнём с простого факта что проц интерпретирует поток бинарный который к нему с памяти припрлывает

поэтому(даже с кэшировананием чтения) если условие внутри цИкла аля функция хэвисайда - проще (в смысле общая производительность выполнения в долгую игнорируя потерю реентерабельности участка кода) однократно модифицировать код в какой то момент чем на каждой итерации проверять по какой ветке бежать

всё это скуфня измышления будущего в прошедшем

qulinxao3 ★☆
()
Ответ на: комментарий от qulinxao3

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

Jullyfish
() автор топика
Ответ на: комментарий от chumpa

Зачем? 🙀️

Чем так коды писать, запилили бы ассмеблер, пусть он переводит mov и всё остальное в эти коды. Всяко проще будет и быстрее, если уж сишку тяжко портировать/не лезет/инструкции специфические.

peregrine ★★★★★
()
Ответ на: комментарий от sergej

(: forth lit :)

и в целом если для x86 через тригерение по unckown opcode int6 расширение своими интерпретациями :\

qulinxao3 ★☆
()
Ответ на: комментарий от qulinxao3

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

Вот можешь же нормально писать? Нахрен постоянно косплеить зеленого чебуратора из звездных войн?

yax123 ★★★★★
()
Ответ на: комментарий от yax123

дык когда 1кб апартаменты тогда такты коллеги (в белом халате)

а ща терабайт налево облако на права dup swap ret yoda

гугля ллмка льстит что кручённых язык и прочий себебрянный деканс бес курева это для снижения входного спама от самотключающихся аббонентов см вернона Глубина в небе али Огонь над пропастью али ваще болталка

qulinxao3 ★☆
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария