我正在尝试学习汇编。我使用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