为什么我的ARM汇编计算器程序中出现Seg Faults?

时间:2017-04-07 04:53:35

标签: assembly raspberry-pi3

我在Raspian OS上使用ARM编写计算器程序;它是一个简单的计算器,使用反向抛光表示法,只使用整数,只有4个操作(加+,sub - ,乘*,MAX M)。代码也应该作为连续循环运行。

这是我的代码到目前为止,我可以输入值,但之后我得到一个seg错误。

.global main
.func main

main:
    BL _scanf
    MOV R1, R0  

    BL _getchar
    MOV R3, R0

    BL _scanf
    MOV R2, R0

    BL _compare
    B   main

_getchar:
    MOV R7, #3      
    MOV R0, #0              
    MOV R2, #1            
    LDR R1, =read_char      
    SWI 0                
    LDR R0, [R1]           
    AND R0, #0xFF        
    MOV PC, LR            

_scanf:
    PUSH {LR}
    SUB SP, SP, #4          
    LDR R0, =format_str     
    MOV R1, SP             
    BL scanf                
    LDR R0, [SP]            
    ADD SP, SP, #4          
    POP {PC}                 

_compare:
   CMP R3, #'+'            
   BEQ _add     

   CMP R3, #'-'
   BEQ _sub

   CMP R3, #'*'
   BEQ _mul

   CMP R3, #'M'
   BEQ _max

_add:
   MOV R4, LR
   ADD R0, R1, R2
   MOV R0, R0
   BL printf
   MOV PC, R4

_sub:
   MOV R4, LR
   SUB R0, R1, R2
   MOV R0, R0
   BL printf
   MOV PC, R4

_mul:
   MOV R4, LR
   MUL R0, R1, R2
   MOV R0, R0
   BL printf
   MOV PC, R4

_max:
   MOV R4, LR
   CMP R1, R2
   BL printf
   MOV PC, R4


_exit:  
    MOV R7, #1        
    SWI 0  

  .data
  read_char:    .ascii  " "
  format_str:   .asciz  "%d"

我提前为可怕的格式化道歉,但这是我的第一次。 谢谢。

1 个答案:

答案 0 :(得分:0)

这里有一些非常粗略的代码供参考。

  • 没有用于捕获错误用户输入的控件,因此您可以添加代码 为此。
  • 假设数字<&lt; 2 ^ 31 - 1,所以你可以处理更大 值。
  • 您只有3位运营商,因此您需要添加额外的运营商 代码。
  • 您还需要确保没有堆栈破坏。
  

.data prompt0:.asciz&#34;请输入number1:\ noperator :(添加:   +,sub: - 或乘法:*)\ nthen number2:\ n&#34; get0:.asciz&#34;%d&#34; get1:.asciz&#34;%s&#34; prompt1:.asciz&#34;%d%c%d =%d \ n&#34; .align伪   4 .text .global main .extern scanf,printf,exit main:nop

            sub sp, sp, #(4 * 4)

            ldr r0,=prompt0         // prompt user
            bl _print

            ldr r0,=get0            //get number1
            bl _scan
            push {r0}               // save input

            ldr r0,=get1            // get operator
            bl _scan
            push {r0}               // save input

            ldr r0,=get0            // get number2
            bl _scan
            push {r0}               // save input

            pop {r3}                // for printf
            pop {r2}                // for printf
            pop {r1}                // for printf

            cmp r2, #'+'
            beq add
            cmp r2, #'-'
            beq sub
            cmp r2, #'*'
            beq mul

    add:
            add r4, r1, r3
            b output
    sub:
            sub r4, r1, r3
            b output
    mul:
            mul r4, r1, r3

    output:
            ldr r0,=prompt1
            bl _print


            add sp, sp, #(4 * 4)

    _exit:
            b exit

    _print:
            push {r4,lr}            // we only need r4 for the final output; so waste
            bl printf
            pop {r4, pc}

    _scan:
            push {lr}
            sub sp, sp, #4
            mov r1, sp
            bl scanf
            ldr r0, [sp]
            add sp, sp, #4
            pop {pc}
    .end

输出例如:

pi@raspberrypi:~/asm $ ./calculator_001
Please enter number1: <enter>
operator: (add: +, sub: -, or multiply: *) <enter>
then number2: <enter>
1234
*
6789
1234 * 6789 = 8377626