2017-04-07 64 views
-1

我正在使用ARM在Raspian OS上編寫計算器程序;它是一個簡單的計算器,使用反向拋光表示法,只使用整數,並且只有4個操作(add +,sub - ,multiply *,MAX M)。代碼也應該作爲連續循環運行。爲什麼在我的ARM組件計算器程序中出現Seg故障?

這是我的代碼到目前爲止,我可以輸入值,但之後我得到一個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" 

我爲可怕的格式提前道歉,但這是我第一次。 謝謝。

+0

1)在_getchar你cl​​obber R1中,應該是第一個操作符。 2).data中的字符串不應該是'.align 4'-ed? – Tommylee2k

+0

你能夠使用調試器嗎? – InfinitelyManic

回答

0

下面是一些非常粗略的參考代碼。

  • 有沒有控制捕獲不良的用戶輸入,所以你可以添加代碼 。
  • 數字被假定爲< 2^31 - 1,因此您可以處理更大的 值。
  • 你只有3個運營商,所以你需要添加額外的 的代碼。
  • 您還需要確保沒有堆棧破壞。

。數據prompt0:.asciz 「請輸入數字1:\ noperator:(補充: +,子: - ,或乘:*)\ n然後NUMBER2:\ n」 個get0:.asciz「% d「get1:.asciz」%s「prompt1:.asciz」%d%c%d =%d \ n「.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 

輸出如:

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