2016-07-13 40 views
0

由於我對低級操作感興趣,我在業餘時間學習彙編。 I tried running the code from this tutorialSIGBUS錯誤 - 用於RaspberryPi上ARM處理器的彙編

The code can be found here及以下:

/****************************************************************************** 
* @file float.s 
* @brief simple example of scalar multiplication using the FPU 
* 
* Simple example of using the ARM FPU to compute the multiplication result of 
* two float values 
* 
* @author Christopher D. McMurrough 
******************************************************************************/ 

    .global main 
    .func main 

main: 

    LDR R0, =val1   @ load variable address 
    VLDR S0, [R0]   @ load the value into the VFP register 

    LDR R0, =val2   @ load variable address 
    VLDR S1, [R0]   @ load the value into the VFP register 

    VMUL.F32 S2, S0, S1  @ compute S2 = S0 * S1 

    VCVT.F64.F32 D4, S2  @ covert the result to double precision for printing 
    VMOV R1, R2, D4   @ split the double VFP register into two ARM registers 
    BL _printf_result  @ print the result 

    B _exit    @ branch to exit procedure with no return 

_exit: 
    MOV R7, #4    @ write syscall, 4 
    MOV R0, #1    @ output stream to monitor, 1 
    MOV R2, #21    @ print string length 
    LDR R1, =exit_str  @ string at label exit_str: 
    SWI 0     @ execute syscall 
    MOV R7, #1    @ terminate syscall, 1 
    SWI 0     @ execute syscall 

_printf_result: 
    PUSH {LR}    @ push LR to stack 
    LDR R0, =result_str  @ R0 contains formatted string address 
    BL printf    @ call printf 
    POP {PC}    @ pop LR from stack and return 

.data 
result_str:  .asciz  "Multiplication result = %f \n" 
exit_str:  .ascii  "Terminating program.\n" 
val1:   .float  3.14159 
val2:   .float  0.100 

我編譯在樹莓派做代碼:

gcc -o float float.s 

它編譯沒有任何問題,但是當我運行它,我得到以下錯誤:

Program received signal SIGBUS, Bus error.
0x00010428 in main()

我已經做了一些什麼導致SIGBUS錯誤的研究,唯一的t興我可以想到這裏訪問misaligned內存,但是0x00010428 = 66,600在十進制是可以被4整除,所以我不知道這是什麼問題。

運行

cat/proc/cpuinfo 

我得到如下:

processor: 0
model name: ARMv6-compatible processor rev 7 (v6l)
BogoMIPS: 2.00
Features: half thumb fastmult vfp edsp java tls
CPU implementer: 0x41
CPU architecture: 7
CPU variant: 0x0
CPU part: 0xb76
CPU revision: 7

Hardware: BCM2708
Revision: 0002

+1

'在主0x00010428()'當然對齊,這是其中的指令是使信號,而不是地址進行訪問。用-g再次編譯,然後在gdb中運行。調試器會告訴你錯誤的位置是 – Tommylee2k

+0

你的printf結果函數不會保持堆棧在64位邊界上對齊。也許是這樣嗎? –

+2

可以被4整除你只需要看低兩位。他們需要爲零0x10428結束於8這是0b1000,所以必須在4字節邊界上對齊。 (不需要轉換爲十進制) –

回答

0

運行gdb下代碼顯示問題:

(gdb) b main 
Breakpoint 1 at 0x10424: file float.s, line 16. 
(gdb) r 
Starting program: /home/pi/a.out 

Breakpoint 1, main() at float.s:16 
16   VLDR S0, [R0]   @ load the value into the VFP register 
(gdb) p /x $r0 
$1 = 0x2064e 
(gdb) n 

Program received signal SIGBUS, Bus error. 
main() at float.s:18 
18   LDR R0, =val2   @ load variable address 

SIGBUS上升,因爲地址0x2064e不是4個字節對齊。

val1val2不對齊的4個字節,因爲它們的聲明如下字符串lengh沒有多的4
一種方法來解決這個問題是一個字符串之前移動浮動的聲明是這樣的:

.data 
val1:   .float  3.14159 
val2:   .float  0.100 
result_str:  .asciz  "Multiplication result = %f \n" 
exit_str:  .ascii  "Terminating program.\n" 

有了這個修改運行程序打印:

Multiplication result = 0.314159
Terminating program.

+0

這很有趣,我沒有意識到他們是這樣工作的。所以我想象一下,浮點數和字符串依次存儲在一塊內存中?如果是這樣,另一種方法是填充字符串,直到他們是4字節對齊? –