2014-04-27 26 views
0

我正在嘗試從用戶讀取一個數字,然後使用read()系統調用讀取它。我終於會在原始模式下使用終端,所以我需要使用read()而不是scanf()。下面是我在做什麼:在ARM程序集中使用讀取系統調用

readAndStore: 
    /*Read input*/ 
    mov  r0, #0 /*Set to read from std in*/ 
    mov  r1, sp 
    mov  r2, #1 
    bl  read 
    /*Check whether the number is between 1 and 5 */ 
    ldr  r1, [sp] 
    sub  r0, r1, #0x30 /*For example if '2' is entered: 0x32 - 0x30 = 2 */ 
    cmp  r0, #1 
    bge  second /* If greater than or equal, to go to second */ 
    mov  r0, #1 /*If less than 1, return 1 */ 
    b  return 
second: 
    sub  r0, r1, #0x30 
    cmp  r0, #7 
    ble  store /* If less than or equal to 7, go to store */ 
    mov  r0, #1 /* If not, return 1 */ 
store: 
    /*Code to store result*/ 

    mov  r0, #0 /*Return 0 if input is valid (between 1-5)*/ 
return: 
    pop  {fp, lr}d 
    mov  sp, fp 
    bx lr 

我使用循環主,直到它返回0(意思是輸入有效),其不斷調用此方法readAndStore。

這是當我運行我的程序輸出我得到:

Choose a number: 2 /* I enter number 2 */ 
Choose a number: Choose a number: 

下面是另一個例子:

Choose a number: 22 /* I enter number 22 */ 
Choose a number: Choose a number: Choose a number: 

基本上它只是打印N + 1個號碼輸入提示字符串。我的預測是,這個問題是我在撥打read之前立即將其放入r2中,但我不確定。任何想法我做錯了什麼?

回答

0

要調用單個字符讀,但你使用

ldr  r1, [sp] 

這將加載整個32位字。你的堆棧將包含「隨機」數據,使24位r1隨機。

您應該使用

ldrb  r1, [sp] 

代替。你也必須確保你爲這個值分配堆棧空間。

代碼中還有一些其他缺失的部分,您不檢查讀取值的上邊界(0x39)。該代碼將始終返回0,因爲mov r0,#1總是被mov r0,#0中的「store:」取代0#

+0

謝謝,所以我會在開始時執行'sub sp,sp,#1' readAndStore方法在堆棧上騰出空間? –

+1

根據您的環境,您必須將堆棧大小增加4或8個字節。 ARM EABI需要8個字節的對齊方式,所以你可以使用它保存。所以'sub sp,sp,#8'是正確的選擇。但請記住在再次彈出堆棧中的任何內容之前使用'添加sp,sp,#8'。 –