[英]ARMv8 Assembly, Run into bus error when calling a subroutine
每次我嘗試使用奇怪的命令行參數運行程序時,程序都會遇到總線錯誤。
./test 4 5
bus error (core dumped)
./test 7 13
bus error (core dumped)
但是當我使用命令行參數運行它時,它工作得很好。
./test 12 12
這是我的代碼:
.balign 4
.global main
main:
stp x29, x30, [sp, -48]! //save fp and link register to stack
mov x29, sp //update fp register
mov w28, w0 //move argc to w28
mov x27, x1 //move argv to counter2
//load argv[1]
mov x19, 1
ldr x0, [x27, w19, sxtw 3]
bl atoi
mov x21, x0
//load argv[2]
mov x19, 2
ldr x0, [x27, w19, sxtw 3]
bl atoi
mov x22, x0
//store argc, argv[1], argv[2] in memory
str w28, [x29, 16]
str x21, [x29, 20]
str x22, [x29, 28]
//allocate memory for an array
mul x24, x21, x22
lsl x24, x24, #2
sub x24, xzr, x24
add sp, sp, x24
//call function initializeRandom
ldr x0, [x29, 20]
ldr x1, [x29, 28]
mov x2, sp
bl initializeRandom
//deallocate memory
ldr x21, [x29, 20]
ldr x22, [x29, 28]
mul x24, x21, x22
lsl x24, x24, #2
add sp, sp, x24
mainEnd: //End of main() function
ldp x29, x30, [sp], 48 //restore fp and link registers
ret
////////initializeRandom(int x, int y, int* table) function////////
.balign 4
initializeRandom:
stp x29, x30, [sp, -64]!
mov x29, sp
//end of subroutine
ldp x29, x30, [sp], 64
ret
子程序 initializeRandom 的目的是用隨機數填充在主 function 中創建的數組。 但是當子程序基本上為空時,程序甚至都不會運行。 為什么會發生總線錯誤,我該如何解決?
不同之處在於行為可能是因為,根據代碼中以x24
計算的值,在第 33 行執行add sp, sp, x24
之后, sp
的值將或不會在 16 字節邊界上對齊。 這當然等同於說在使用sp
引用 memory 之前, sp
應始終包含一個0x10
的倍數的值。
這將在第一次嘗試使用sp
訪問 memory 時導致異常,即line stp x29, x30, [sp, -64]!
的initializeRandom()
。
gdb --args ./program 7 13
Reading symbols from ./program...
(gdb) b 33
Breakpoint 1 at 0x7b4: file program.s, line 33.
(gdb) run
Starting program: /home/user/stackoverflow/65167437/program 7 13
Breakpoint 1, main () at program.s:33
33 add sp, sp, x24
(gdb) p/x $sp
$1 = 0xfffffffff300
(gdb) p/x $x24
$2 = 0xfffffffffffffe94
(gdb)
gdb --args ./program 22 22
Reading symbols from ./program...
(gdb) b 33
Breakpoint 1 at 0x7b4: file program.s, line 33.
(gdb) run
Starting program: /home/user/stackoverflow/65167437/program 22 22
Breakpoint 1, main () at program.s:33
33 add sp, sp, x24
(gdb) p/x $sp
$1 = 0xfffffffff300
(gdb) p/x$x24
$2 = 0xfffffffffffff870
(gdb)
請參閱文章在 AArch32 和 AArch64 中使用堆棧:
Rules Specific to AArch64
For AArch64, sp must be 16-byte aligned whenever it is used to access memory. This is enforced by AArch64 hardware.
This means that it is difficult to implement a generic push or pop operation for AArch64. There are no push or pop aliases like there are for ARM and Thumb.
The hardware checks can be disabled by privileged code, but they're enabled in at least Linux and Android.
如果您添加代碼以將x24
中計算的值四舍五入到最接近的16/0x10
倍數,您的程序應該可以使用任意參數值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.