回覆列表
  • 1 # 邢州巔峰數碼

    寫彙編的基本已經絕跡了現在,就老一輩的有些在用

    #include <stdio.h>

    #include <sys/time.h>

    #define INIT_TIMER_VALIABLE \

    struct timeval tpstart,tpend; \

    float timeuse;

    #define START_TIMER gettimeofday(&tpstart,NULL);

    #define END_PRINTF_TIMER(name) \

    gettimeofday(&tpend,NULL); \

    timeuse=(tpend.tv_sec*1000*1000+tpend.tv_usec)-(tpstart.tv_sec*1000*1000+tpstart.tv_usec); \

    printf("func :%s:time use(us) %f\n",name,timeuse);

    float vfp_operate(float f1, float f2)

    {

    float sum=0;

    __asm__ __volatile__(

    "vmov s1, %1\n"

    "vmov s2, %2\n"

    "fmuls s0, s1, s2\n"

    "vmov %0, s0\n"

    :"=r"(sum)

    :"r"(f1),"r"(f2)

    );

    return sum;

    }

    int main()

    {

    float f1,f2;

    float result;

    INIT_TIMER_VALIABLE

    printf("input float data1:");

    scanf("%f",&f1);

    printf("input float data2:");

    scanf("%f",&f2);

    START_TIMER

    result=f1*f2;

    END_PRINTF_TIMER("use system function")

    printf("result is %f\n",result);

    START_TIMER

    result=vfp_operate(f1,f2);

    END_PRINTF_TIMER("use vfp_operate")

    printf("result is %f\n",result);

    }

    /*

    測試結果:

    ./vfp_helloworld

    input float data1:0.125

    input float data2:1.684

    func :use system function:time use(us) 12.000000

    result is 0.210500

    func :use system function:time use(us) 5.000000

    result is 0.210500

    */

    測試使用編譯選項 :

    原始碼:

    #include <stdio.h>

    int main()

    {

    float f1,f2;

    printf("input float data1:");

    scanf("%f",&f1);

    printf("input float data2:");

    scanf("%f",&f2);

    printf("float %f x %f =%f\n", f1,f2,f1*f2);

    }

    編譯選項:(只是多增加了-mfloat-abi=softfp 測試發現=sofltfp和=hard編譯出的彙編一樣)

    arm-none-linux-gnueabi-gcc vfp_helloworld.c -S arm-none-linux-gnueabi-gcc vfp_helloworld.c -S -o vfp_helloworld.asm

    -mfloat-abi=softfp -o vfp_helloworld.asm

    .cpu arm10tdmi .cpu arm10tdmi

    .eabi_attribute 27, 3 .fpu softvfp

    .fpu vfp .eabi_attribute 20, 1

    .eabi_attribute 20, 1 .eabi_attribute 21, 1

    .eabi_attribute 21, 1 .eabi_attribute 23, 3

    .eabi_attribute 23, 3 .eabi_attribute 24, 1

    .eabi_attribute 24, 1 .eabi_attribute 25, 1

    .eabi_attribute 25, 1 .eabi_attribute 26, 2

    .eabi_attribute 26, 2 .eabi_attribute 30, 6

    .eabi_attribute 30, 6 .eabi_attribute 18, 4

    .eabi_attribute 18, 4 .file "vfp_helloworld.c"

    .file "vfp_helloworld.c" .section .rodata

    .section .rodata .align 2

    .align 2 .LC0:

    .LC0: .ascii "input float data1:\000"

    .ascii "input float data1:\000" .align 2

    .align 2 .LC1:

    .LC1: .ascii "%f\000"

    .ascii "%f\000" .align 2

    .align 2 .LC2:

    .LC2: .ascii "input float data2:\000"

    .ascii "input float data2:\000" .global __aeabi_f2d

    .align 2 .global __aeabi_fmul <<<------這裡說明軟體浮點運算。

    .LC3: .align 2

    .ascii "float %f x %f =%f\012\000" .LC3:

    .text .ascii "float %f x %f =%f\012\000"

    .align 2 .text

    .global main .align 2

    .type main, %function .global main

    main: .type main, %function

    .fnstart main:

    .LFB2: .fnstart

    @ args = 0, pretend = 0, frame = 16 .LFB2:

    @ frame_needed = 1, uses_anonymous_args = 0 @ args = 0, pretend = 0, frame = 16

    stmfd sp!, {fp, lr} @ frame_needed = 1, uses_anonymous_args = 0

    .save {fp, lr} stmfd sp!, {r4, r5, r6, r7, r8, fp, lr}

    .LCFI0: .save {r4, r5, r6, r7, r8, fp, lr}

    .setfp fp, sp, #4 .LCFI0:

    add fp, sp, #4 .setfp fp, sp, #24

    .LCFI1: add fp, sp, #24

    .pad #32 .LCFI1:

    sub sp, sp, #32 .pad #36

    .LCFI2: sub sp, sp, #36

    ldr r0, .L3 .LCFI2:

    bl printf ldr r0, .L3

    sub r3, fp, #8 bl printf

    ldr r0, .L3+4 sub r3, fp, #32

    mov r1, r3 ldr r0, .L3+4

    bl scanf mov r1, r3

    ldr r0, .L3+8 bl scanf

    bl printf ldr r0, .L3+8

    sub r3, fp, #12 bl printf

    ldr r0, .L3+4 sub r3, fp, #36

    mov r1, r3 ldr r0, .L3+4

    bl scanf mov r1, r3

    flds s15, [fp, #-8] bl scanf

    fcvtds d5, s15 ldr r3, [fp, #-32] @ float

    flds s15, [fp, #-12] mov r0, r3

    fcvtds d6, s15 bl __aeabi_f2d

    flds s14, [fp, #-8] mov r5, r0

    flds s15, [fp, #-12] mov r6, r1

    fmuls s15, s14, s15 <<<-----直接使用硬體浮點指令 ldr r3, [fp, #-36] @ float

    fcvtds d7, s15 mov r0, r3

    fstd d6, [sp, #0] bl __aeabi_f2d

    fstd d7, [sp, #8] mov r7, r0

    ldr r0, .L3+12 mov r8, r1

    fmrrd r2, r3, d5 ldr r3, [fp, #-32] @ float

    bl printf ldr r2, [fp, #-36] @ float

    sub sp, fp, #4 mov r0, r3

    ldmfd sp!, {fp, pc} mov r1, r2

    .L4: bl __aeabi_fmul <<<------這裡呼叫軟體浮點運算。

    .align 2 mov r3, r0

    .L3: mov r0, r3

    .word .LC0 bl __aeabi_f2d

    .word .LC1 mov r3, r0

    .word .LC2 mov r4, r1

    .word .LC3 stmia sp, {r7-r8}

    .LFE2: str r3, [sp, #8]

    .fnend str r4, [sp, #12]

    .size main, .-main ldr r0, .L3+12

    .ident "GCC: (Sourcery G++ Lite 2009q1-203) 4.3.3" mov r2, r5

    .section .note.GNU-stack,"",%progbits mov r3, r6

    bl printf

    sub sp, fp, #24

    ldmfd sp!, {r4, r5, r6, r7, r8, fp, pc}

    .L4:

    .align 2

    .L3:

    .word .LC0

    .word .LC1

    .word .LC2

    .word .LC3

    .LFE2:

    .fnend

    .size main, .-main

    .ident "GCC: (Sourcery G++ Lite 2009q1-203) 4.3.3"

    .section .note.GNU-stack,"",%progbits

    摘自:RM的pdf文件 的說明

    浮點運算的支援

    ARM 處理器核心不包含浮點硬體。 必須使用以下兩種方法之一,另行提供對浮點演算法的支援:

    在軟體中,使用浮點庫 fplib。 此庫提供了執行浮點運算可以呼叫的函式,無需額外的硬體。 請參閱《庫指南》 中第 4-2 頁的軟體浮點庫 fplib。

    在硬體中,使用含 VFP 硬體協處理器的 ARM 處理器核心來進行所需的浮點運算。 VFP 是執行 IEEE 浮點的協處理器體系結構,支援單精度和雙精度,但不支援擴充套件精度。

    Note

    在實際程式設計中,VFP 中的浮點運算實際是組合使用硬體(執行常見的情況)和軟體(處理不常見的情況和導致異常的情況)執行的。 請參閱VFP 支援。

    Example 5.2 是一個用 C 執行浮點演算法的函式,用以說明浮點演算法的軟體和硬體支援的不同。

    Example 5.2. 浮點運算

    float foo(float num1, float num2)

    {

    float temp, temp2;

    temp = num1 + num2;

    temp2 = num2 * num2;

    return temp2-temp;

    }

    如果使用命令列選項 --cpu 5TE --fpu softvfp 編譯Example 5.2 的 C 程式碼,則編譯器生成的機器程式碼的反彙編如Example 5.3 所示。 在本示例中,在軟體中透過呼叫庫例程(如 __aeabi_fmul)來執行浮點演算法。

    Example 5.3. 軟體中對浮點運算的支援

    ||foo|| PROC

    PUSH {r4-r6, lr}

    MOV r4, r1

    BL __aeabi_fadd <<<<----直接向加

    MOV r5, r0

    MOV r1, r4

    MOV r0, r4

    BL __aeabi_fmul <<<<<----然後相乘

    MOV r1, r5

    POP {r4-r6, lr}

    B __aeabi_fsub

    ENDP

    如果使用命令列選項 --fpu vfp 編譯Example 5.2 的 C 程式碼,則編譯器生成的機器程式碼的反彙編如Example 5.4 所示。 在本示例中,在硬體中透過浮點演算法指令(如 VMUL.F32)來執行浮點演算法。

    Example 5.4. 硬體中對浮點運算的支援

    ||foo|| PROC

    VADD.F32 s2, s0, s1

    VMUL.F32 s0, s1, s1

    VSUB.F32 s0, s0, s2

    BX lr

    ENDP

    在實際程式設計中,使用硬體支援浮點演算法的程式碼更為緊湊,並提供比在軟體中執行浮點演算法的程式碼更佳的效能。 但是,浮點演算法的硬體支援需要 VFP 協處理器。

    預設情況下,如果有 VFP 協處理器,則會生成 VFP 指令。 如果沒有 VFP 協處理器,則編譯器會生成呼叫軟體浮點庫 fplib 的程式碼,用於執行浮點運算。fplib 是 C 庫 RealView Development Suite 標準分發的組成部分。

  • 中秋節和大豐收的關聯?
  • 哪一瞬間,讓你下定決心放下一個人?