使用尾调用优化打印换行符

问题描述

伊戈尔·日尔科夫 (Igor Zhirkov) 的书Low-Level Programming 中有这个未解决的问题:

"尝试在不调用print_char或复制其代码的情况下重写print_newline。提示:阅读 关于尾调用优化。”。

我花了一些时间阅读有关尾调用优化的文章,但我不知道正确的做法是什么。

原始代码(无尾调用):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

什么是尾调用优化?

解决方法

为了参考,我也会在这个线程中提供解决方案。

  1. 没有优化
print_newline:
    mov rdi,10
    call print_char
    ret
print_char:
    push rdi
    mov rdi,rsp 
    call print_string 
    pop rdi
    ret
  1. 尾调用优化。指令序列 call Xret 总是可以用 jmp X 代替。
print_newline:
    mov rdi,10
    jmp print_char
print_char:
    push rdi
    mov rdi,rsp 
    call print_string 
    pop rdi
    ret
  1. 刚刚陷入print_char;基本上是创建一个带有两个入口点的子程序。
print_newline:
    mov rdi,10
print_char:
    push rdi
    mov rdi,rsp 
    call print_string 
    pop rdi
    ret

Here is a more in-depth explanation in my blog

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...