2015-12-06 274 views
2

我目前正在寫一個函數,應該基本上只是將字符串中的字符寫入變量。as8088變量初始化

當執行測試打印我的變量看起來很好。但是,當我試圖打印第一個變量賦值(inchar)的函數外返回一個空字符串,但第二個變量(outchar)似乎返回正常。我以某種方式覆蓋第一個變量?

這是我的代碼:

_EXIT = 1 
_READ = 3 
_WRITE = 4 
_STDOUT = 1 
_STDIN = 1 
_GETCHAR = 117 
MAXBUFF = 100 

.SECT .TEXT 
start: 
0: PUSH endpro2-prompt2 
    PUSH prompt2 
    PUSH _STDOUT 
    PUSH _WRITE 
    SYS 
    ADD SP,8 
    PUSH 4 
    PUSH buff 
    CALL getline 
    ADD SP,4 
    !!!!!!!!! 
    PUSH buff 
    CALL gettrans 
    ADD SP,4 
    ADD AX,1 !gives AX an intial value to start loop 
1: CMP AX,0 
    JE 2f 
    PUSH endpro-prompt1 
    PUSH prompt1 
    PUSH _STDOUT 
    PUSH _WRITE 
    SYS 
    ADD SP,8 
    PUSH MAXBUFF 
    PUSH buff 
    CALL getline 
    ADD SP,2 
    !PUSH buff 
    !CALL translate 
    !ADD SP,4 
    JMP 1b 
2: PUSH 0    ! exit with normal exit status 
    PUSH _EXIT   
    SYS 

getline: 
    PUSH BX 
    PUSH CX 
    PUSH BP 
    MOV BP,SP 
    MOV BX,8(BP) 
    MOV CX,8(BP) 
    ADD CX,10(BP) 
    SUB CX,1 

1: CMP CX,BX 
    JE 2f 
    PUSH _GETCHAR 
    SYS 

    ADD SP,2 
    CMPB AL,-1 
    JE 2f 
    MOVB (BX),AL 
    INC BX 
    CMPB AL,'\n' 
    JNE 1b 

2: MOVB (BX),0 
    MOV AX, BX 
    SUB AX,8(BP) 
    POP BP 
    POP CX 
    POP BX 
    RET 
gettrans: 
    PUSH BX 
    PUSH BP 
    MOV BP,SP 
    MOV BX,6(BP) !Store argument in BX 
    MOVB (inchar),BL ! move first char to inchar 


1: INC BX 
    CMPB (BX),' ' 
    JE 1b 
    MOVB (outchar),BL !Move char seperated by Space to outchar 

    MOV AX,1 !On success 
    POP BP 
    POP BX 
    RET 

.SECT .BSS 
buff: 
    .SPACE MAXBUFF 

.SECT .DATA 
prompt1: 
    .ASCII "Enter a line of text: " 
endpro: 

prompt2: 
    .ASCII "Enter 2 characters for translation: " 
endpro2:  

outchar: 
    .BYTE 0 
inchar: 
.BYTE 0 
charct: 
    .BYTE 0 
wordct: 
    .BYTE 0 
linect: 
    .BYTE 0 
inword: 
    .BYTE 0 

這是用於測試打印

PUSH 1  ! print that byte 
PUSH inchar 
PUSH _STDOUT 
PUSH _WRITE 
SYS 
ADD SP,8 
CALL printnl !function that prints new line 

PUSH 1  ! print that byte 
PUSH outchar 
PUSH _STDOUT 
PUSH _WRITE 
SYS 
CALL printnl 
ADD SP,8 
+0

你怎麼稱呼'gettrans' ? – Downvoter

+0

編輯!如果這可以幫助發現問題,我可以發佈我的整個代碼。 –

+0

-Michael Petch在完成這些建議的更改後,我的結果似乎保持不變。如果我指向地址而不是內容,我的程序會返回'r'作爲outchar,'p'則返回inchar。我會再多一些。感謝你目前的幫助。 –

回答

2

似乎有一些as88 8088仿真環境。但我在很多的代碼庫中注意到了這一點bug提到:

1. The assembler requires sections to be defined in the following order: 
     TEXT 
     DATA 
     BSS 

After the first occurrences, remaining section directives may appear in any order. 

我會在你的代碼建議後移動BSS部分數據在as88環境有事件類似的問題。


在你原來的代碼,你有這樣的臺詞:

MOV (outchar),BX 
[snip] 
MOV (inchar),BX 

您outchar定義INCHAR爲字節。上面的2行將2個字節(16位)從寄存器BX移動到兩個字節變量。這會導致CPU將額外的字節寫入內存中的下一個變量。你想明確地移動一個字節。像這樣的東西可能更合適:

MOVB (outchar),BL 
[snip] 
MOVB (inchar),BL 

正如你會看到這樣的代碼仍然有一個錯誤,因爲我提的這個答案後。澄清 - MOVB指令將從BL移動一個字節並將其放入變量。


當你做一個SYS呼籲,寫你需要傳遞的緩衝區的地址進行打印,而不是在緩衝區中的數據。你有2條這樣的線:

PUSH (inchar) 
[snip] 
PUSH (outchar) 

括號表示採取變量中的值,並將它們推入堆棧。 SYS WRITE要求顯示字符的地址。可以把自己的地址代碼應該是這樣的:

PUSH inchar 
[snip] 
PUSH outchar 

gettrans函數在處理一個字節從一個緩衝區複製到另一個嚴重的缺陷。你有代碼,這是否:

MOV BX,6(BP) !Store argument in BX 
    MOVB (inchar),BL ! move first char to inchar 

1: INC BX 
    CMPB (BX),' ' 
    JE 1b 
    MOVB (outchar),BL !Move char seperated by Space to outchar 

MOV BX,6(BP)正確的地方作爲參數傳遞的是緩衝區地址,並把它變成BX。有似乎是看起來像行的一個問題:

MOVB (inchar),BL ! move first char to inchar 

這不是做什麼意見建議它應該。上面的行將BX中的緩衝區地址的低位字節(BL)移動到變量inchar。您要移動BX指向的內存位置的字節,並將其放入inchar。不幸的是,在x86上,你不能直接將數據從一個內存操作數移動到另一個內存操作數。爲了解決這個問題,你必須將數據從BX指向的緩衝區中移動到一個臨時寄存器(我將選擇CL),然後將其移至變量。代碼看起來是這樣的:

MOVB CL, (BX) 
MOVB (inchar),CL ! move first char to inchar 

然後,您必須爲outchar做相同的,所以在這兩個地方的修補程序可能類似於此:

MOV BX,8(BP) !Store argument in BX 
    MOVB CL, (BX) 
    MOVB (inchar),CL ! move first char to inchar 

1: INC BX 
    CMPB (BX),' ' 
    JE 1b 

    MOVB CL, (BX) 
    MOVB (outchar),CL ! move second char to outchar 
2

指令代碼MOV (inchar),BX存儲寄存器BX到標inchar的存儲器位置。

然而,inchar已被定義爲一個.BYTE,但BX是一個16位寄存器,(2個字節),所以你不僅inchar而且outchar寫入。

它開始工作的唯一原因是因爲8088是低端架構,所以BX的低位字節先存儲,而高位字節跟在後面。

所以,儘量MOV (inchar),BL

+0

我試過了,請看看上面的編輯。它似乎沒有解決問題,MOV也應該是MOVB(MOV似乎不能編譯) –

+0

'gettrans'仍然包含'MOV(inchar),BX'。無論如何,沒有對a)的明確描述進行故障排除是毫無意義的,恰恰會發生什麼情況,以及b)恰恰相反,你會發生什麼。如果我指出了一個錯誤並且解決了它,那麼原始問題的問題可能已經解決,並且您可能只是面臨着代碼的下一個問題,但是在stackoverflow上會有一個新問題。 –

+0

這個程序在這個時候的目標是讀取由2個空格分隔的字符組成的行。我想抓住第一個字符並將其存儲在變量(inchar)中我想抓住第二個變量並將其存儲在(outchar)中。 –