我正在努力学习装配.我使用NASM而不是AT&T语法.
这是我的第一个程序,它比较两个命令行参数和输出哪个是最小的(如果它们相等则支持第一个).
我想我做错了.我注意到堆栈随着compare的每次"调用"而增长,所以我可以通过尾递归优化来改善它.但是,我不知道如何正确地做到这一点.我应该用其他东西替换所有出现的'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
Run Code Online (Sandbox Code Playgroud)
是的,你应该用call
s 替换jmp
s.通常,call
当您希望执行在调用返回时在下一行继续执行时,您应该使用.在你的代码中,执行永远不会返回,因为compare
它只是一个循环,所以jmp
进入下一次迭代的正确方法也是如此.对于call report
你拥有的两个实例也是如此.
至于你的第二个问题,jl
不改变标志,所以jg
在它之后调用没有问题.
归档时间: |
|
查看次数: |
1431 次 |
最近记录: |