2015-06-23 76 views
1

我正在編寫一個16位實模式彙編程序。函數運行多次,但只調用一次

這裏是代碼的頂部:

org 100h 
jmp start 

%include "memory.asm" 

str: db "aBc", 0 
outstr: times 100 db 0 

start: 
    mov si, str 
    mov di, outstr 
    call english_to_morse 
    jmp $ 

正如你所看到的,我只是打電話english_to_morse一次。

這裏是english_to_morse功能:

english_to_morse: 
    pusha 
    call str_to_lower 

    pusha;    BREAKPOINT 
    mov ah, 0Eh 
    mov al, 'a' 
    int 10h 
    popa 

.next: 
    lodsb 
    push si;    get_morse_from_alpha will trash SI 

    cmp al, 0 
    je .end 
    cmp al, 'a' 
    jl .next 
    cmp al, 'z' 
    jg .next 

    call get_morse_from_alpha 
    call print_morse_letter 

    pop si 
    jmp .next 

.end: 
    ret 

正如你可以在這裏看到,就是在這裏完成的是.next標籤上的唯一的循環;不是整個子程序。

然而,當我運行此,這裏是輸出:

a._ _..._._. 

大約一百倍(基本上,這只是打印了一遍又一遍,直到突然停止)。

我的目標是讓這個功能只運行一次。


這是與NASM彙編程序組裝並在DOSBOX中執行的。

+0

我沒有兩個pusha和一個popa。不太合乎邏輯。 –

回答

2

english_to_morse開頭,你有一個pusha,但在ret之前沒有相應的popa

2

我看到您的代碼有2個問題。

  • 正如Michael指出的pusha未與popa匹配。
  • 您太早推SI寄存器。

    1. jl .nextjg .next都將繼續推送額外的SI寄存器,永遠不會彈出!
    2. je .end忘記彈出SI註冊表。

既然你知道get_morse_from_alpha將垃圾SI只是把push si正上方是電話。

.next: 
lodsb 
cmp al, 0 
je .end 
cmp al, 'a' 
jl .next 
cmp al, 'z' 
jg .next 
push si;    get_morse_from_alpha will trash SI 
call get_morse_from_alpha 
call print_morse_letter 
pop si 
jmp .next 
.end: 
popa 
ret 

我不禁注意到你使用了簽名比較。在這個小小的代碼片段中沒有傷害,但是如果你想考慮完整的ASCII範圍[0,255],這種習慣會給你帶來麻煩。更好地使用jbja

相關問題