Assembly putchar是否清除堆栈?
我正在用Assembly putchar是否清除堆栈?,assembly,x86-64,callstack,calling-convention,putchar,Assembly,X86 64,Callstack,Calling Convention,Putchar,我正在用putchar、push和pop进行一些修补。 当我尝试推送rcx的值,对其进行处理,调用putchar并将其弹出回rcx时,我发现rcx中的值已更改为0。 就像第一段代码一样 为了进行比较,我制作了第二位代码,在这里我按下了rcx,用它做了一些不是putchar的事情,然后把它放回rcx,rcx仍然是它按下的值 mov rcx, 123 push rcx inc rcx call [putchar] pop rcx call [putchar] putchar是否确实清除了堆栈?
putchar
、push
和pop
进行一些修补。
当我尝试推送rcx
的值,对其进行处理,调用putchar
并将其弹出回rcx时,我发现rcx
中的值已更改为0。
就像第一段代码一样
为了进行比较,我制作了第二位代码,在这里我按下了rcx
,用它做了一些不是putchar
的事情,然后把它放回rcx
,rcx
仍然是它按下的值
mov rcx, 123
push rcx
inc rcx
call [putchar]
pop rcx
call [putchar]
putchar
是否确实清除了堆栈?
有人知道如何保护堆栈(或至少是堆栈的重要部分)不受此影响吗?我怀疑您没有考虑到
putchar
的正确调用要求。你在哪个站台?哪种建筑?在该体系结构上,ABI为调用约定声明了什么?putchar的实际定义是什么?我使用的是Windows x64体系结构,第一个(int)参数应该在rcx中。putchar
的定义是intputchar(intc)代码>。调用putchar
之前,int
返回到rax
并等于rcx
的值,因此实际上不需要堆栈来保存rcx
的值。我仍然想知道如何保留堆栈。在调用putchar
之前,似乎没有在堆栈上为寄存器参数区域分配32个字节。此外,在进行任何调用之前,您应该确保堆栈是16字节对齐的。请参阅:。被调用方(被调用的函数)可以随意修改堆栈上的32个字节。在您的代码中,rcx
中的值恰好成为寄存器参数区域的一部分,因此可以被覆盖。@PeterCordes:What-we-don;t know是函数的上下文。例如,如果有一个典型的stackframe,没有其他值被推送,则不需要进一步对齐。如果没有stackframe(RBP未推送),则需要通过从RSP中减去8(加上任何可被16整除的本地堆栈空间要求)来重新调整堆栈。现在,这不考虑以后推送另一个值,如rcx
。仅指通常在为局部变量分配空间时发生的对齐,以及通常进行重新对齐的临时空间。
mov rcx, 123
push rcx
inc rcx
pop r12
call [putchar]
mov rcx, r12
call [putchar]