2016-07-13 5 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ヒンジ私はここでは、4で割り切れる小数点で0x00010428 = 66,600しかし、不整合メモリにアクセスしていると考えることができるので、私は問題が何であるか分かりません。

cat/proc/cpuinfo 

を実行

は、私は、次を得る:

GDBの下でコードを実行する

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で割り切れる場合は、下位の2ビットを見るだけで済みます。ゼロにする必要があります.0x10428は8で終わります。これは0b1000なので、確かに4バイトの境界に揃えられます。 (小数点に変換する必要はありません) –

答えて

0

問題を示しています。アドレス0x2064eは4つのバイトではないので

(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が発生します整列した。

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

:この問題を解決するための4
一つの方法のlenghない複数との宣言フォロー文字列は、このような文字列の前にフロートの宣言を移動することですので、

val1val2は整列4つのバイトではありませんこの修正プログラムのプリントを実行すると:確かに整列された命令は、アドレスがアクセスされない、信号を引き起こすことがある場合

メインで

Multiplication result = 0.314159
Terminating program.

+0

それは面白いです、私は彼らがそのように働いたことを認識しませんでした。だから私はフロートや文字列がメモリのブロックに順次格納されることを描いている?もしそうなら、4バイト整列されるまで別の方法で文字列をパディングするのでしょうか? –

関連する問題