2012-02-19 5 views
2

펌웨어 모듈을 작성하려고합니다. 기존 펌웨어에는 소스 코드가 없습니다. 모든 Thumb 코드.펌웨어 패치를위한 ARM/Thumb 코드 ... gcc 어셈블러/링커를 BL로 절대 addr로 연결하는 방법은 무엇입니까?

사람이 어떻게 gcc as (GAS) 어셈블러에서이 작업을 수행하는 어떤 생각을 가지고 않습니다 BL '나의 코드에서 기존의 일부 기능 (에 보내고 할 때 수동으로 오프셋을 계산하지 않고 사용 BL ..하지만 난 내가 BL을 사용하려는 경우

현재 알고 자신의 주소), ... 난에 있습니다 내 코드 -figure 아웃 돌아 가자 가자하고 모든 이전의 지침을 조립하여 발생 될 모든 바이트를 추가 함수를 쓰고 있어요 - 내 함수의 시작 주소를 추가 (내가 지정 링커 스크립트에서 쓰고있는 것의 시작 주소) - 전화하고자하는 firmfunc 함수의 주소를 빼십시오.

이 모든 것 ... 가능할 수있는 오프셋을 계산하는 것입니다. bl 오프셋을 쓰면 기존 펌웨어 기능을 호출 할 수 있습니까? 그리고 그 BL 전에 코드를 변경하면 수동으로 다시해야합니다! 내가 잘 BX를 사용하는 방법을 배우게 할 이유
참조 .. 이 내가 꽤 BX를 이해하지 못하고, 대신 BL

의 ...입니다. 내가 BX를 사용하여 절대 주소로 이동할 경우, Thumb 코드에서 lsb 바이트 1을 유지하기 위해 Thumb 코드를 계산할 때 실제 주소를 1 씩 증가시켜야합니까 ... CPU가 엄지 코드를 알 수 있습니까?

답변

3

BIG 편집 :

내가 최근에 배운 것을 기반으로 대답하고 내가 주소로 BL을 생성하기 위해 링커에게 잘 모릅니다 질문

우선의 더 나은 이해를 변경하는 하드 코드 된 주소이며 실제로이 코드에 없습니다. 레이블과 같은 코드가 있거나없는 코드가있는 엘프 파일을 조작 해 봅니다. 링커를 속일 수 있는지 없는지는 알 수 없습니다. 링커 스크립트도 수정해야합니다. 그럴 가치가 없어. 이 일에서 양산 된

다른 질문 :

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

또는 명령을 저장하고 그냥이

LDR R6, =0x24001 
BX R6 
을이 분기 들어

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

잘 작동합니다

링크를 연결하려는 경우 주소를 알고 있어야합니다. 당신은 엄지 손가락 모드에 있고 당신이 팔 모드에서 시작하는 경우 엄지 손가락 코드를 다음

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 밤은 할) 수 있다는 것을 알아야합니다.

매우 죄송 다른 대답을 오해, 난 그 mov 인 LR을 맹세 할 수, PC는 모드와 lsbit으로 당겨하지만 나던.

+0

대하여 절대 아니다를에만 프로그램 카운터 상대 주소로 분기 할 수있다. 이것은 고정 된 단어 길이 명령 세트입니다. bx를 사용하여 모드를 전환 할 수는 있지만 레지스터로 제한됩니다. 위에서 설명한대로 또는 가능하면 모드에 기반하여 사용하십시오 (암 모드에서만 작동 할 수도 있음) ldr pc , = function_name은 긴 분기이고 다른 단어를 사용합니다 (가변 길이 길이 명령어와 같습니다)하지만 bx는 분기 링크가 아닌 분기입니다. –

+0

감사합니다. 좋은 설명입니다. 하지만 나는 펌웨어에서 기존의 엄지 손가락 기능을 BL로 할 수 있기를 원합니다. 그 주소는 알고 있습니다. 이런 방식으로 나는 LR을 망쳐 놓지 않아도되지만 어셈블러 나 링커 스크립트에 넣는 방법을 모르겠다. BL 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 

즉시 값이 (가)에 들어갈 오프셋 PC에 충분히 가까운 경우 즉각적인 필드이면 verneer (trampoline)는 건너 뛰고 지정된 상수 주소로 단일 분기 명령어를 얻습니다.

[1] codesorcery와 (2009q1) 툴체인 사용 : 이제 명령 BL의 부호화 보면 arm-none-eabi-gcc -march=armv7-a -x assembler test.spp -o test.elf -Ttext=0x1000000 -nostdlib