User Tag List

Показано с 1 по 10 из 29

Тема: Программирование голого железа Raspberry Pi

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #5
    Administrator Аватар для CityAceE
    Регистрация
    13.01.2005
    Адрес
    г. Москва
    Сообщений
    4,579
    Записей в дневнике
    7
    Спасибо Благодарностей отдано 
    407
    Спасибо Благодарностей получено 
    1,208
    Поблагодарили
    394 сообщений
    Mentioned
    48 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Система команд Thumb

    Итак, давайте потихоньку двигаться дальше. Предлагаю внести в пример из предыдущего сообщения небольшие изменения. А именно, после строки с директивой org добавить ещё три строки:
    Код:
        blx start
        thumb
    start:
    То есть по итогу должно получиться вот так:


    Так как мы что-то добавили в программу, то исполняемый код должен увеличиться на несколько байт. Давайте скомпилируем и проверим. И что мы видим? Исполняемый код стал объёмом 46 байт, то есть ещё короче чем был! А был, напомню, 54 байта.

    Что же произошло? Давайте попробуем разобраться и дизассемблировать код обеих вариантов с помощью популярного дизассемблера IDA Pro.

    Вот так выглядит код первоначального варианта (54 байта):



    Всё совпадает с ассемблерным текстом! (На команду MOV R0 не обращайте внимания. По умолчанию IDA для простоты восприятия заменяет некоторые последовательности команд в метакоманды. Вот и здесь она заменила две команды загрузки регистра R0 по половинкам (MOV и MOVT) в одну длинную загрузку, которая на самом деле отсутствует в наборе команд процессоров ARM. Где-то в настройках IDA Pro это можно отключить и тогда всё будет отображаться, как есть.)

    А вот так выглядит дизассемблер модифицированного варианта (46 байт):



    И тоже всё совпадает, и даже дополнительная команда BLX появилась. Но при этом код стал короче!

    А произошло следующее: директивой thumb мы дали команду ассемблеру все дальнейшие команды вместо стандартного 32-х битного режима ассемблировать в 16-битном режиме thumb. А, собственно, командой BLX мы дали понять процессору, что код, на который будет осуществлён дальнейший переход, будет исполняться в режиме thumb.

    В режиме thumb все команды, в отличие от 32-х битного режима, кодируются только двумя байтами. В результате исполняемый код такой программы становится более компактным. И всё было бы отлично, если бы не кое-какие ограничения. И прежде всего это ограниченный набор команд - их всего лишь 36. Есть и другие ограничения, но сейчас не будем на них останавливаться.

    Что касается меня, то режим thumb привлёк моё внимание именно ограниченным набором команд. Дело в том, что за долгую историю архитектуры ARM было выпущено несколько поколений процессоров. Для них было придумано большое количество команд, у каждой из которых есть свои особенности. Разобраться и изучить их все довольно проблематично. А здесь же мы имеем только 36 команд, с помощью которых можно запрограммировать практически любое действие. При этом, если вам когда-нибудь вдруг станет тесно в рамках thumb, вы всегда сможете перейти на 32-х битную систему команд без необходимости что-то менять в своём коде. Наверное, здесь можно привести аналогию с процессорами i8080 (КР580ВМ80А) и Z80. Если писать код для процессора i8080 (аналогия с thumb), то код будет работать и на i8080, и на Z80. Но если вам становится тесно, то вы можете начать использовать дополнительные регистры и команды процессора Z80 (аналогия с 32-х битным режимом ARM), но тогда уже потеряете совместимость с i8080.

    В конце хочу привести полный список из 36 команд процессоров ARM в режиме thumb:

    Мнемоника Команда Пример Эквивалент кода ARM
    1 ADC Сложение с учетом переноса ADC Rd, Rs ADCS Rd, Rd, Rs
    2 ADD Сложение ADD Rd, Rs, Rn ADD Rd, Rs, Rn
    3 AND Логическое "И" AND Rd, Rs ANDS Rd, Rd, Rs
    4 ASR Арифметический сдвиг вправо ASR Rd, Rs MOVS Rd, Rd, ASR Rs
    5 B Безусловный переход B label B label
    6 BCC Переход по условию CC BCC label BCC label
    7 BIC Сброс битов (маскирование) BIC Rd, Rs BICS Rd, Rd, Rs
    8 BL Переход со ссылкой BL label BL label
    9 BX Переход и смена режима ядра BX Hs BX Hs
    10 CMN Сравнение с отрицанием CMN Rd, Rs CMN Rd, Rs
    11 CMP Сравнение CMP Rd, #Offset8 CMP Rd, #Offset8
    12 EOR Исключающее "ИЛИ" EOR Rd, Rs EORS Rd, Rd, Rs
    13 LDMIA Групповая загрузка регистров LDMIA Rb!, {Rlist} LDMIA Rb!, {Rlist}
    14 LDR Загрузка целого слова LDR Rd, [PC, #lmm] LDR Rd, [PC, #lmm]
    15 LDRB Загрузка байта LDRB Rd, [Rb, Ro] LDRB Rd, [Rb, Ro]
    16 LDRH Загрузка полуслова LDRH Rd, [Rb, #lmm] LDRH Rd, [Rb, #lmm]
    17 LSL Логический сдвиг влево LSL Rd, Rs, #Offset5 MOVS Rd, Rs, LSL #Offset5
    18 LDRSB Загрузка байта со знаком LDRSB Rd, [Rb, Ro] LDRSB Rd, [Rb, Ro]
    19 LDRSH Загрузка полуслова со знаком LDRSH Rd, [Rb, Ro] LDRSH Rd, [Rb, Ro]
    20 LSR Логический сдвиг вправо LSR Rd, Rs MOVS Rd, Rd, LSR Rs
    21 MOV Пересылка MOV Rd, #Offset8 MOVS Rd, #Offset8
    22 MUL Умножение MUL Rd, Rs MULS Rd, Rs, Rd
    23 MVN Пересылка с инверсией MVN Rd, Rs MVNS Rd, Rs
    24 NEG Инверсия (побитовое "НЕ") NEG Rd, Rs RSBS Rd, Rs, #0
    25 ORR Логическое "ИЛИ" ORR Rd, Rs ORRS Rd, Rd, Rs
    26 POP Извлечение регистров из вершины стека POP {Rlist} LDMIA R13!, {Rlist}
    27 PUSH Размещение регистров в вершине стека PUSH {Rlist} STMDB R13!, {Rlist}
    28 ROR Циклический сдвиг вправо ROR Rd, Rs MOVS Rd, Rd, ROR Rs
    29 SBC Вычитание с переносом SBC Rd, Rs SBCS Rd, Rd, Rs
    30 STMIA Групповое сохранение регистров STMIA Rb!, {Rlist} STMIA Rb!, {Rlist}
    31 STR Сохранение целого слова STR Rd, [Rb, Ro] STR Rd, [Rb, Ro]
    32 STRB Сохранение байта STRB Rd, [Rb, Ro] STRB Rd, [Rb, Ro]
    33 STRH Сохранение полуслова STRH Rd, [Rb, Ro] STRH Rd, [Rb, Ro]
    34 SWI Программное прерывание SWI Value8 SWI Value8
    35 SUB Вычитание SUB Rd, Rs, Rn SUBS Rd, Rs, Rn
    36 TST Побитовая проверка TST Rd, Rs TST Rd, Rs

    Rs - Регистр-источник (Register source)
    Rd - Регистр-приёмник (Register destination)
    Ro - Отступ (Register offset)
    Rn - Второй аргумент в арифметических операциях
    Rlist - Список регистров
    Последний раз редактировалось CityAceE; 24.08.2023 в 15:18.
    С уважением, Станислав.

  2. Эти 5 пользователя(ей) поблагодарили CityAceE за это полезное сообщение:

    ALS (24.08.2023), creator (26.08.2023), Oleg N. Cher (25.08.2023), Outcast (07.03.2024), svofski (24.08.2023)

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Raspberry Pi 400 - альтернатива ZX Spectrum Next?
    от CityAceE в разделе Зарубежные компьютеры
    Ответов: 26
    Последнее: 03.11.2020, 23:48
  2. Эмуляторы ZX Spectrum для Raspberry Pi
    от CityAceE в разделе Эмуляторы
    Ответов: 32
    Последнее: 01.10.2019, 18:23

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •