2012-02-19 3 views
2

Я пытаюсь написать модем прошивки (к существующей прошивке, для которой у меня нет исходного кода) Весь код большого пальца.Код ARM/Thumb для исправлений прошивки ... Как рассказать gcc-ассемблер/компоновщик к BL к абсолютному addr?

ли кто-нибудь есть идеи, как сделать это, в gcc as (GAS) ассемблере: Использование BL без необходимости вручную вычислять смещения, когда BL «ИНГ некоторые существующие функции (не в моем коде .. но я знать его адрес)

в настоящее время, если я хочу использовать BL ... я должен: -Перейти назад в моем коде -figure из и добавить все байты, которые будут получены в результате сборки всех предыдущих инструкций в function Я пишу -add начальный адрес моей функции к этому (я указываю начальный адрес того, что я пишу, в сценарии компоновщика) , а затем вычесть адрес функции firmfunc, которую я хочу назвать

Все это ... просто для расчета смещения ... для возможности написать смещение bl ... для вызова существующей функции прошивки? И если я изменю любой код до BL, я должен сделать это заново вручную!
См .. поэтому я хочу научиться использовать BX право ... вместо BL

Кроме того, я не совсем понимаю BX. Если я использую BX для перехода на абсолютный адрес, мне нужно увеличить фактический адрес на 1, когда вы закачиваете код Thumb из кода Thumb (чтобы сохранить байт lsb 1) ... и CPU будет знать, что это код большого пальца?

ответ

3

BIG EDIT:

Изменение ответ, основанный на том, что я недавно узнал, и лучшее понимание вопроса

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

ваш другой вопрос, который был порожден от этого:

Arm/Thumb: using BX in Thumb code, to call a Thumb function, or to jump to a Thumb instruction in another function

Для ветвления это работает просто отлично:

LDR R6, =0x24000 
ADD R6, #1  @ (set lsb to 1) 
BX R6 

или сохранить команду и просто сделать это

LDR R6, =0x24001 
BX R6 

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

ldr r6,=0x24001 
    bl thumb_trampoline 
    ;@returns here 
    ... 
.thumb_func 
thumb_trampoline: 
    bx r6 

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

ldr r6,=0x24001 
    bl arm_trampoline 
    ;@returns here 
    ... 
arm_trampoline: 
    bx r6 

Вы должны знать, что вы можете мусор r6 таким образом (убедитесь r6 экономии некоторое значение используется код, который называется этот код Isnt).

Очень жаль вводить вас в заблуждение другим ответом, я могу поклясться, что mov lr, pc вытащил lsbit в качестве режима, но это не так.

+0

теперь, если вы посмотрите на кодировке для бл инструкции относительно не является абсолютным, вы можете переходить только на адреса относительно счетчика команд. Это набор инструкций с фиксированным набором слов, вам нужно либо использовать bx, который позволяет переключать режим, но ограничивается регистрами, использовать его, как я показал выше или, если возможно, на основе режима (возможно, работает только в режиме руки) ldr pc , = function_name, которое является длинной ветвью и использует другое слово (например, переменную длину слова), но как bx является веткой, а не веткой. –

+0

Спасибо, за хорошее объяснение. Но я хотел бы иметь возможность BL для существующих функций большого пальца в прошивке, для которых я знаю адрес. Таким образом, мне не нужно связываться с LR, но я не знаю, как это сделать в ассемблере ... или скрипте компоновщика ... например, если я делаю BL LABEL, я должен сказать ассемблеру, какой адрес LABEL есть ... потому что это не в моем коде ... и не знаю, как сказать, что – vmanta

+0

я приму ответ, это хорошая информация ... все равно, если кто-нибудь знает .. ответ pls. Должен быть способ. Как ссылка компоновщика на импортируемые вами функции (внешние функции кодовых вызовов) - какая директива для использования в сценарии asm или компоновщика? – vmanta

0

Принятый ответ достигает желаемой цели, но, чтобы ответить на него точно так же, как вам было предложено, вы можете использовать директиву .equ, чтобы связать постоянную ячейку с символом, которая затем может использоваться в качестве операнда для инструкций. Это ассемблер синтезируют батут, если/когда необходимо:

equ myFirmwareFunction, 0x12346570 
.globl _start 
     mov r0, #42 
     b myFirmwareFunction 

, который генерирует следующую сборку [1]

01000000 <_start>: 
1000000: e3a0002a mov r0, #42 ; 0x2a 
1000004: eaffffff b 1000008 <__*ABS*0x12346570_veneer> 

01000008 <__*ABS*0x12346570_veneer>: 
__*ABS*0x12346570_veneer(): 
1000008: e51ff004 ldr pc, [pc, #-4] ; 100000c <__*ABS*0x12346570_veneer+0x4> 
100000c: 12346570 data: #0x12345670 

Если непосредственное значение находится достаточно близко к ПК, что смещение будет соответствовать в немедленное поле, то verneer (trampoline) пропущен, и вы получите одну инструкцию перехода к указанному постоянному адресу.

[1] с использованием codesorcery (2009q1) с набора инструментов: arm-none-eabi-gcc -march=armv7-a -x assembler test.spp -o test.elf -Ttext=0x1000000 -nostdlib