使用尾调用优化打印换行符 [英] print a newline using tail call optimization
问题描述
Igor Zhirkov 的著作 Low-Level Programming 中有这个未解决的问题:
There's this unanswered question in the Igor Zhirkov's book Low-Level Programming :
"尝试在不调用print_char或复制其代码的情况下重写print_newline.提示:阅读关于尾调用优化.".
"Try to rewrite print_newline without calling print_char or copying its code. Hint: read about tail call optimization.".
我花了一些时间阅读有关尾调用优化的文章,但我不知道正确的做法是什么.
I've spent some times reading about tail call optimization, but I can't figure out what would be the proper way of doing it.
原始代码(无尾调用):print_newline =>print_char =>print_string=>string_length=>print_string
Original code (without tail-call): print_newline => print_char => print_string=>string_length=>print_string
string_length:
xor rax, rax
.loop:
cmp byte [rdi+rax], 0 ; if rdi = 0 (not an address), then seg fault
je .end
inc rax
jmp .loop
.end:
ret
print_string:
push rdi
call string_length
pop rsi
mov rdx, rax
mov rax, 1
mov rdi, 1
syscall
ret
print_char:
push rdi
mov rdi, rsp
call print_string
pop rdi
ret
print_newline:
mov rdi, 10
jmp print_char
什么是尾调用优化?
推荐答案
为了参考,我也会在这个线程中提供解决方案.
For the sake of reference I will provide the solution in this thread too.
- 没有优化
print_newline:
mov rdi, 10
call print_char
ret
print_char:
push rdi
mov rdi, rsp
call print_string
pop rdi
ret
- 尾调用优化.
call X
和ret
指令序列总是可以被jmp X
替换.
- A tail call optimization. A sequence of instructions
call X
andret
can always be substituted byjmp X
.
print_newline:
mov rdi, 10
jmp print_char
print_char:
push rdi
mov rdi, rsp
call print_string
pop rdi
ret
- 刚刚陷入
print_char
;基本上是创建一个带有两个入口点的子程序.
- Just falling into
print_char
; basically making a subroutine with two entry points.
print_newline:
mov rdi, 10
print_char:
push rdi
mov rdi, rsp
call print_string
pop rdi
ret
这篇关于使用尾调用优化打印换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!