Files
linux-kernel-module-cheat/userland/arch/arm/ldr_pseudo.S
Ciro Santilli 六四事件 法轮功 5f935ee53d readme: verify all non-README links with asciidoctor/extract-header-ids and git grep
Fix all the ~30 failures it found!
2019-06-09 00:00:00 +00:00

66 lines
1.8 KiB
ArmAsm

/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-ldr-pseudo-instruction */
#include <lkmc.h>
LKMC_PROLOGUE
/* Mnemonic for a PC relative load:
*
* ....
* ldr r0, [pc, offset]
* r0 = myvar
* ....
*/
ldr r0, myvar
LKMC_ASSERT_EQ(r0, =0x12345678)
/* Mnemonic PC relative load with an offset.
* Load myvar2 instead of myvar.
*/
ldr r0, myvar + 4
LKMC_ASSERT_EQ(r0, =0x9ABCDEF0)
/* First store the address in r0 using a magic =myvar, which creates
* a new variable containing the address and PC-relative addresses it
* https://stackoverflow.com/questions/17214962/what-is-the-difference-between-label-equals-sign-and-label-brackets-in-ar
*
* Use the adr instruction would likely be better for this application however.
*
* ....
* r0 = &myvar
* r1 = *r0
* ....
*/
ldr r0, =myvar
ldr r1, [r0]
LKMC_ASSERT_EQ(r1, =0x12345678)
/* More efficiently, use r0 as the address to read, and write to r0 itself. */
ldr r0, =myvar
ldr r0, [r0]
LKMC_ASSERT_EQ(r0, =0x12345678)
/* Same as =myvar but store a constant to a register.
* Can also be done with movw and movt. */
ldr r0, =0x11112222
LKMC_ASSERT_EQ(r0, =0x11112222)
/* We can also use GAS tolower16 and topper16 and movw and movt
* to load the address of myvar into r0 with two immediates.
*
* This results in one extra 4 byte instruction read from memory,
* and one less data read, so it is likely more cache efficient.
*
* https://sourceware.org/binutils/docs-2.19/as/ARM_002dRelocations.html
*/
movw r0, #:lower16:myvar
movt r0, #:upper16:myvar
ldr r1, [r0]
LKMC_ASSERT_EQ(r1, =0x12345678)
LKMC_EPILOGUE
myvar:
.word 0x12345678
myvar2:
.word 0x9ABCDEF0