2011-11-07 24 views
1

我想學習Y86,所以我做了一個非常簡單的程序。它有三個長整數的數組,並且每個塊由要求輸入用戶通過rdint填充。在第一個Y86程序中沒有得到輸出

編譯後的(?)程序要求輸入三個,但不能打印出來。

代碼:

Main: irmovl Array, %edx 
rdint %eax 
rmmovl %eax, 0(%edx) 
rdint %eax 
rmmovl %eax, 4(%edx) 
rdint %eax 
rmmovl %eax, 8(%edx) 

irmovl $10, %edi 
Print: irmovl Array, %edx 
    mrmovl 0(%edx), %eax 
    wrch %eax 
    wrch %edi 
    mrmovl 4(%edx), %eax 
    wrch %eax 
    wrch %edi 
    mrmovl 8(%edx), %eax 
    wrch %eax 
    wrch %edi 

    halt 

    .align 4 

Array: 
    .long 0 
    .long 0 
    .long 0 

我輸入:

0 
1 
2 

輸出:

(three blank lines below) 



Stopped in 22 steps at PC = 0x47. Exception 'HLT', CC Z=1 S=0 O=0 
Changes to registers: 
%edx: 0x00000000  0x0000004c 
%edi: 0x00000000  0x0000000a 

Changes to memory: 
0x0004: 0x024008f2  0x00000001 
0x0008: 0x00000000  0x00000002 

Changes to memory: 0x0004: 0x024008f2  0x00000001 0x0008: 
0x00000000  0x00000002 

回答

0

有一個經典的問題與程序:缺乏新線在伊蘇文件,導致YAS行爲不端。

第一個問題是由於YAS中的錯誤。如果您查看YAS生成的yo文件,您將看到最後的.long 0語句永遠不會被定義。您可能還會看到,yo文件中的第一行操作碼是0x00,即nop(當YAS遇到沒有關聯換行符的最終指令時,它將其包裝起來,擰緊yo文件)

這意味着您鬆散第一個irmovl數組,%edx(它變成某種廢話,可能是0x00000000,即4個nops),所以你寫第一個讀字符x'30'(ascii for'0')到edx指向的位置(這可能是0x00000000)在第一條指令中(這是4個nops - 記住你讀了一個字符,但它最終在一個4字節的寄存器中並保存爲這樣)。所以你正在寫入0x00000000和地址那是0x00000000,這對YIS來說意味着寄存器沒有被改變,因此它不會在「更改到內存」轉儲部分中顯示。

你同第二讀取重複這一點,在第二個字寫00000001(在該位置,覆蓋指令),並與第三讀,在第三個字寫0x00000002(在該位置覆蓋的指令。)

現在,當然,你完全暢飲!您將指針重置爲數組(使用edx)並嘗試打印內容,但Array(0),Array(4)和Array(8)包含0x00000000,因爲這是您定義的內容(使用。由於Y86中未定義內存的默認設置爲0x00000000,所以Array(0)和Array(4)的長4條語句自動爲Array(8),所以程序打印x'00'(因爲您打印一個字符從一個4字節的字,當然,這是垃圾)

你會注意到,這符合從YIS的轉儲eax不顯示,因爲它從0x00000000,它的初始值。edx和edi外觀A-OK,edi指向Array(8),唯一改變的內存是程序的第二個和第三個字(它們分別被0x00000001和0x00000002覆蓋)

所以,總結。 YAS犯了一個錯誤。您必須通過在最後的.long 0語句之後添加新行來克服此問題。 YIS會誤導你,因爲,批判地說!,當你用數據覆蓋代碼時,它不會拋出異常。

+0

您尚未表明您發佈的鏈接來自您自己的網站,這是必需的。無論如何,我已經刪除了它們,因爲它們不是必需的。 –