我正在嘗試學習彙編。我使用NASM而不是AT & T語法。彙編中的尾遞歸
這是我的第一個程序,它比較兩個命令行參數並輸出哪一個是最小的(有利於第一個以防它們相等)。
我想我做錯了。我注意到堆棧隨着比較的每次「調用」而增長,所以我可以使用尾遞歸優化使其更好。但是,我不知道如何正確做到這一點。我是否應該用其他的東西替換所有出現的'call',比如jmp? 我讀過,跳躍的方式也取決於你如何與Linux內核和/或libc有關'函數'對象(我不與libc鏈接,因此沒有主'功能'),這使我很困惑我以爲我會來這裏尋求簡單的建議。另外,我的另一個問題是,如果「jl」跳轉實際上改變了標誌內容,所以「jg」也會跳轉,那麼「jl」立即跟着「jg」會引起不希望的行爲是多麼愚蠢。是否有雙向的「原子」跳躍?
section .data
usage: db 'Please provide two strings',10
usageLen: equ $-usage
bigger: db 'It is bigger!',10
biggerLen: equ $-bigger
smaller: db 'It is smaller!',10
smallerLen: equ $-smaller
section .text
global _start
_start:
pop ebx ; argc
cmp ebx, 3
jne usage_exit
pop eax ; argv[0]
pop eax
pop ebx
call compare ;
usage_exit:
mov eax, 4 ; sys_write
mov ebx, 1 ; int fd = stdout
mov ecx, usage
mov edx, usageLen
int 80h ; call kernel
mov eax, 1 ; sys_exit
mov ebx, 0 ; int status = 0
int 80h ; call kernel
report:
mov ecx, eax
mov edx, ebx
mov eax, 4 ; sys_write
mov ebx, 1 ; int fd = stdout
int 80h ; call kernel
mov eax, 1 ; sys_exit
mov ebx, 0 ; int status = 0
int 80h ; call kernel (exit)
compare:
push eax
push ebx
mov eax, [eax]
mov ebx, [ebx]
test ax, ax
jz is_smaller
test bx, bx
jz is_bigger
cmp ax, bx
jl is_smaller
jg is_bigger
; if the same, try next positions
pop ebx
pop eax
inc eax
inc ebx
call compare
is_smaller:
mov eax, smaller
mov ebx, smallerLen
call report
is_bigger:
mov eax, bigger
mov ebx, biggerLen
call report