arm64汇编学习 - (6)adr和adrp
本篇博客是基于对苯叔的第三季视频的学习整理而得,大家如果想深入学习可以购买《arm64体系结构编程与实践》以及购买苯叔出品的第三季视频。
1 adr
Form PC-relative address adds an immediate value to the PC value to form a PC-relative address, and writes the result to the destination register.
Literal variant
ADR <Xd>, <label>
Decode for this encoding
integer d = UInt(Rd);
bits(64) imm;
imm = SignExtend(immhi:immlo, 64);
Assembler symbols
- Is the 64-bit name of the general-purpose destination register, encoded in the “Rd” field.
Operation
bits(64) base = PC[];
X[d] = base + imm;
2 ADRP
Form PC-relative address to 4KB page adds an immediate value that is shifted left by 12 bits, to the PC value to form a PC-relative address, with the bottom 12 bits masked out, and writes the result to the destination register.
Literal variant
ADRP <Xd>, <label>
Decode for this encoding
integer d = UInt(Rd);
bits(64) imm;
imm = SignExtend(immhi:immlo:Zeros(12), 64);
Assembler symbols
Xd Is the 64-bit name of the general-purpose destination register, encoded in the “Rd” field.
Operation
bits(64) base = PC[];
base<11:0> = Zeros(12);
X[d] = base + imm;
3 adr/adrp/ldr使用
3.1 测试代码
.global adrp_test
adrp_test:
/*使用adr来读取my_test_data的地址和值*/
adr x0, my_test_data
/*使用adrp指令来读取my_test_data的地址和值*/
adrp x1, my_test_data
add x1, x1, #:lo12:my_test_data
ldr x3, [x1]
/*使用ldr指令来读取my_test_data地址和值*/
ldr x4, =my_test_data
ldr x5, my_test_data
/*分别使用adrp和ldr来加载位于4MB地址处的init_pg_dir*/
adrp x2, init_pg_dir
ldr x6, =init_pg_dir
ret
3.2 加载地址和运行地址一致
SECTIONS
{
. = 0x80000,
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
. = ALIGN(0x8);
bss_begin = .;
.bss : { *(.bss*) }
bss_end = .;
. = 0x400000,
init_pg_dir = .;
. += 4096;
}
3.3 加载地址和运行地址不一致
SECTIONS
{
. = 0xffff000000080000,
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
. = ALIGN(0x8);
bss_begin = .;
.bss : { *(.bss*) }
bss_end = .;
. = ALIGN(4096);
init_pg_dir = .;
. += 4096;
}
add-symbol-file benos.elf 0x80030 -s .text.boot 0x80000 -s .rodata 0x80758