Unix 在系统调用之前保存寄存器值

Unix 在系统调用之前保存寄存器值,unix,assembly,nasm,cpu-registers,Unix,Assembly,Nasm,Cpu Registers,在我的x86 ASM教科书中,有一个宏的示例,它在标准输出流中写入字符串: %macro PRINT 1 pusha pushf jmp %%astr %%str db %1, 0 %%strln equ $-%%str %%astr: _syscall_write 1, %%str, %%strln popf popa %endmacro 我不明白的是,为什么我们要将所有通用寄存器的值推送到堆栈或从堆栈中弹出\u syscall\u write

在我的x86 ASM教科书中,有一个宏的示例,它在标准输出流中写入字符串:

%macro  PRINT 1
    pusha
    pushf
    jmp %%astr
%%str   db  %1, 0
%%strln equ $-%%str
%%astr: _syscall_write 1, %%str, %%strln
    popf
    popa
%endmacro

我不明白的是,为什么我们要将所有通用寄存器的值推送到堆栈或从堆栈中弹出<代码>\u syscall\u write不会修改任何寄存器,但会保存系统调用结果的
EAX
。那么我们为什么不直接按下并弹出
EAX
?这不是更有效吗?

为了理智起见,你有没有试着按下EAX,然后检查其他寄存器以确保它们是相同的?@alex我只是试着按下并弹出
EAX
,所有寄存器都和我预期的一样<代码>ESP当然会来回更改。这可能是一种最佳做法,即推送和弹出,因为该函数可能会修改寄存器。我想这取决于你希望代码有多高效(对于某些用途,比如这样,性能的提高似乎不值得未来潜在的维护问题)。@alex谢谢你的回答。我还是不明白你第一句话的意思。在
push
ing和
pop
ing
EAX
之后,一些寄存器是否会更改?我相信,系统调用可能会更改它们,之后不会清理。但我已经有一段时间没有使用x86汇编了。