ldr r0, #0x28
ldr
명령은 무엇입니까? 오프셋에서 문자열을로드합니까? 실제로로드 된 문자열 / 값을 어떻게 찾을 수 있습니까?
댓글
답변
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 */
둘 다 동일합니다. 어셈블러는 레이블을 올바른 오프셋으로 변환합니다.
STR에는 ARMv8의 LDR과 같은 PC 기준 주소가 없습니다. 먼저 레지스터에 주소를 계산하면됩니다. https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999
=#0x28
가 아닌 div>의#0x28
?