1

I'm learning assembly in my spare time as i'm interested in low level operations. I tried running the code from this tutorial.

The code can be found here and below:

/******************************************************************************
* @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

I compile the code in the Raspberry Pi doing:

gcc -o float float.s

It compiles without any issues, but when I run it I get the following error:

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

I've done some research into what causes a SIGBUS error, and the only thing I can think of here is accessing misaligned memory, however 0x00010428 = 66,600 in decimal which is evenly divisible by 4, so i'm not sure what the issue is.

Running

cat/proc/cpuinfo

I get the following:

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

fuz
  • 88,405
  • 25
  • 200
  • 352
daviegravee
  • 171
  • 2
  • 12
  • 1
    `0x00010428 in main()` surely is aligned, it's where the instruction is that causes the Signal, not the address accessed. Compile again with -g, and run in inside gdb. the debugger will show you where the error is – Tommylee2k Jul 13 '16 at 13:07
  • your printf result function does not keep the stack aligned on a 64 bit boundary. maybe that is it? – old_timer Jul 13 '16 at 13:25
  • 2
    divisible by 4 you just need to look at the lower two bits. they need to be zero 0x10428 ends in 8 which is 0b1000 so certainly aligned on a 4 byte boundary. (no need to convert to decimal) – old_timer Jul 13 '16 at 13:28
  • 1
    Add `.align 4` before `val1:`. – EOF Jul 13 '16 at 18:51

1 Answers1

1

Running the code under gdb show the problem:

(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 is raised because address 0x2064e is not 4 bytes aligned.

val1 and val2 are not 4 bytes aligned because their declaration follow string with lengh not multiple of 4.
One way to solve this problem is to move declaration of float before strings like this :

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

With this modification running the program prints :

Multiplication result = 0.314159
Terminating program.

mpromonet
  • 11,326
  • 43
  • 62
  • 91
  • That's interesting, I didn't realise they worked like that. So i'm picturing that the floats and strings get stored in a block of memory sequentially then? If so, would another method be to pad out the strings until they are 4 byte aligned? – daviegravee Jul 15 '16 at 00:02