adrpを使って関数を呼び出してみる
code:test.c
long foo = 4649;
void bar(long x) {
printf("%ld\n", x);
}
int main() {
bar(foo);
return 0;
}
アセンブリを出力
code:sh
gcc -S test.c
出力されたアセンブリ
code:test.s
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 12, 0 sdk_version 13, 1
.globl _bar ; -- Begin function bar
.p2align 2
_bar: ; @bar
.cfi_startproc
; %bb.0:
stp x29, x30, sp, #16 ; 16-byte Folded Spill .cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
mov x9, sp
adrp x0, l_.str@PAGE
add x0, x0, l_.str@PAGEOFF
bl _printf
ldp x29, x30, sp, #16 ; 16-byte Folded Reload ret
.cfi_endproc
; -- End function
.globl _main ; -- Begin function main
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
stp x29, x30, sp, #16 ; 16-byte Folded Spill .cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
str w8, sp, #8 ; 4-byte Folded Spill adrp x8, _foo@PAGE
bl _bar
ldr w0, sp, #8 ; 4-byte Folded Reload ldp x29, x30, sp, #16 ; 16-byte Folded Reload ret
.cfi_endproc
; -- End function
.section __DATA,__data
.globl _foo ; @foo
.p2align 3
_foo:
.quad 4649 ; 0x1229
.section __TEXT,__cstring,cstring_literals
l_.str: ; @.str
.asciz "%ld\n"
.subsections_via_symbols
adrp を使って関数を呼び出すように書き換えてみる。
code:diff
diff --git a/load_label_test/test.s b/load_label_test/test.s
index 8c43a70..23e2ced 100644
--- a/load_label_test/test.s
+++ b/load_label_test/test.s
@@ -39,7 +39,12 @@ _main: ; @main
adrp x8, _foo@PAGE
- bl _bar
+
+ ; adrp を使って関数のアドレスを取得する
+ adrp x1, _bar@PAGE
+ add x1, x1, _bar@PAGEOFF
+ blr x1
+
ldr w0, sp, #8 ; 4-byte Folded Reload ldp x29, x30, sp, #16 ; 16-byte Folded Reload 書き換えたアセンブリを実行する
code:sh
$ gcc test.s
$ ./a.out
4649