[英]ARMv8 Assembly, Run into bus error when calling a subroutine
Every time I try to run the program with odd command line argument, the program runs into a bus error.每次我尝试使用奇怪的命令行参数运行程序时,程序都会遇到总线错误。
./test 4 5
bus error (core dumped)
./test 7 13
bus error (core dumped)
But when I run it with even command line argument, it works just fine.但是当我使用命令行参数运行它时,它工作得很好。
./test 12 12
Here is my code:这是我的代码:
.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
The subroutine initializeRandom's purpose is to populate the array created in main function with random numbers.子程序 initializeRandom 的目的是用随机数填充在主 function 中创建的数组。 But the program doesn't even run when the subroutine is basically empty.
但是当子程序基本上为空时,程序甚至都不会运行。 Why does a bus error occur and how do I fix it?
为什么会发生总线错误,我该如何解决?
The difference is behavior may be because, depending on the value that was computed in x24
in your code, the value of sp
will or will not be aligned on a 16 bytes boundary after having executed add sp, sp, x24
at line #33.不同之处在于行为可能是因为,根据代码中以
x24
计算的值,在第 33 行执行add sp, sp, x24
之后, sp
的值将或不会在 16 字节边界上对齐。 This is of course equivalent to say that sp
shall always contain a value which is a multiple of 0x10
prior to using sp
for referencing memory.这当然等同于说在使用
sp
引用 memory 之前, sp
应始终包含一个0x10
的倍数的值。
This will cause an exception at the first attempt to access memory using sp
, that is at the line stp x29, x30, [sp, -64]!
这将在第一次尝试使用
sp
访问 memory 时导致异常,即line stp x29, x30, [sp, -64]!
of initializeRandom()
.的
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)
Please refer to article Using the Stack in AArch32 and AArch64 :请参阅文章在 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.
if you add code for rounding-up the value computed in x24
to the nearest multiple of 16/0x10
, your program should work with arbitrary argument values.如果您添加代码以将
x24
中计算的值四舍五入到最接近的16/0x10
倍数,您的程序应该可以使用任意参数值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.