ldr 명령어는 ARM에서 어떻게 작동합니까?

ldr r0, #0x28 

ldr 명령은 무엇입니까? 오프셋에서 문자열을로드합니까? 실제로로드 된 문자열 / 값을 어떻게 찾을 수 있습니까?

댓글

  • 확실합니까? '=#0x28가 아닌 div>의 #0x28?

답변

LDR은 메모리에서 32 비트 상수 (LDRH (하프 워드) : 16 비트, LDRB (바이트) : 8 비트)를 지정된 대상 레지스터 (예 : r0)로로드합니다.

32 비트 상수는 32 비트 opcode (또는 Thumb 명령어의 경우 16 비트)로 인코딩 할 수 없기 때문에 어셈블러는 참조하는 명령어에 가까운 텍스트 세그먼트에 상수를 저장 한 다음 ( 일반적으로) PC 상대 주소 지정, 즉 r15로부터의 오프셋.

따라서 ldr은 실제로 의사 명령어입니다. 다음 코드

 .code 32 main: ldr r0, =0x12345678 bx lr 

어셈블러에 의해

00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678 

가능한 한 참조하십시오. 원래 ldr 명령어에서 참조 된 상수는 실제로 명령어 자체가 아니라 주소 0x8에 저장됩니다. 그런 다음 주소 0의 ldr 명령어는 PC 기준 주소 지정을 사용하여이 값을 참조합니다. 실제 PC 값은 항상 현재 명령어의 주소 + 8이므로 PC에 대한 오프셋은 0 (8이 아님)입니다. 이는 호환성을 위해 보존해야하는 초기 ARM 프로세서 파이프 라인의 영향입니다.

답변

다음으로 간단히 번역 할 수 있습니다.

r0 = 0x28; 

ARM 어셈블리에서 #는 즉치 값을 표시하고 r0, r1, …는 레지스터입니다. ldr 명령어는 다음과 같은 구문 형식을 취할 수 있습니다 (첫 번째 줄은 사용자 이름 임).

LDR{type}{cond} Rt, [Rn {, #offset}] ; immediate offset LDR{type}{cond} Rt, [Rn, #offset]! ; pre-indexed LDR{type}{cond} Rt, [Rn], #offset ; post-indexed LDRD{cond} Rt, Rt2, [Rn {, #offset}] ; immediate offset, doubleword LDRD{cond} Rt, Rt2, [Rn, #offset]! ; pre-indexed, doubleword LDRD{cond} Rt, Rt2, [Rn], #offset ; post-indexed, doubleword 

Answer

ldr (=는 PC 상대로드를 수행합니다.

이것은 레이블과 숫자 모두에 해당됩니다.

물론 거의 사용하지 않습니다. 어셈블리에서 직접 번호. 라벨없이 디스 어셈블리를 제공했을 수도 있습니다.

GNU GAS ARMv8에서 다음 두 작업을 모두 수행했습니다. 라벨 포함 :

 ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

오프셋 포함 :

 ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

둘 다 동일합니다. 어셈블러는 레이블을 올바른 오프셋으로 변환합니다.

어설 션이있는 GitHub 업스트림 .

STR에는 ARMv8의 LDR과 같은 PC 기준 주소가 없습니다. 먼저 레지스터에 주소를 계산하면됩니다. https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다