2012-09-19 57 views
0

我編寫了IA32的以下彙編腳本。它應該從stdin中讀取一個數字,將其增加並將其輸出到stdout,但它不像預期的那樣工作,它不會打印任何東西(也許stdin的讀取不會終止,或者打印出來的東西是錯誤的?)彙編:從標準輸入讀取整數,遞增並打印到標準輸出

.section .text 
    .globl _start 

_start: 
    movl $3, %eax  # use syscall 3 (read) to read from stdin 
    movl $0, %ebx  # reads from stdin (FD 0) 
    movl %edi, %ecx # store input in register %edi 
    movl $4, %edx  # read one byte 
    int $0x80  # invoke system call to read from stdin 

    incl %edi   # increment the value we got from stdin 

    movl $4, %eax  # use syscall 4 (write) to print to screen 
    movl $1, %ebx  # print to stdout (FD 1) 
    movl %edi, %ecx # pointer to text to write out 
    movl $4, %edx  # length of text to write out (1 byte) 
    int $0x80   # invoke system call to write to stdout 

    movl $1, %eax  # use syscall 1 (exit) to exit 
    movl $0, %ebx  # error code = 0 
    int $0x80   # invoke system call 

您是否看到錯誤?對於任何幫助,我感謝你在前進,

一切順利, 西蒙

+0

只是好奇。這看起來像Linux程序集,對嗎? – Linuxios

+0

是的,這是Linux程序集 – saimn

回答

3
movl %edi, %ecx # store input in register %edi 
movl $4, %edx  # read one byte 

這部分是完全錯誤的。您不能將讀取結果存儲在寄存器中。實際上做的是將結果存儲在%edi中包含的地址中,因爲您尚未設置該地址,可能是您沒有任何業務存儲的地方。你首先需要騰出空間存儲字符串。你也讀了四個字節,而不是一個。

我將取代像這樣的東西

subl $4, %esp 
movl %esp, %ecx 
movl $4, %edx 

這將騰出空間棧上的4個字節,然後使用堆棧的頂部的地址存儲在字符串。您還必須修改寫入系統調用的參數才能使用此地址。

你必須處理的另一個問題是stdin和stdout通常處理文本,所以你讀的可能是一個字符串而不是一個數字,將它用作你將要使用的數字將其轉換並在將其寫出之前將其轉換回來。

+0

謝謝德克,如果我確實忽略鏈接incl%esp它複製輸入,所以傳遞的值實際上起作用。如何解決將字符串轉換爲數字的問題? – saimn

+1

@saimn不,它不起作用。這似乎是%edi是否指向允許你寫作的地方。看看文檔;寫入需要一個地址,而不是一個值。要轉換爲數字,循環遍歷字符並保持總計運行並將每個字符轉換爲數字(從中減去字符'0'),然後將舊的總數乘以10並添加數字。 –

+0

對不起,我的意思是它適用於您的解決方案。然後ommitting incl%esp複製輸入。感謝您的轉換提示。 – saimn

相關問題