我正在阅读" Gray Hat Python"。本书讲授调试技术,您可以通过调试器更改变量值。
在下面的代码中,作者教我们如何更改counter
变量值。但是我想做更多,所以我将'Hello'
参数添加到printf
函数中,以便我可以将其更改为'Bye'
之类的其他内容。
我通过调试器发现的是'Hello'
存储在堆中。存储'Hello'
的堆中的地址保存在堆栈中;为什么呢?
我的问题是:基于存储在堆栈上的一些参数和堆上的一些参数是什么?
from ctypes import *
import time
msvcrt = cdll.msvcrt
counter = 99999999
while 1:
msvcrt.printf("Loop iteration %d!\n" , counter, "Hello")
time.sleep(2)
counter += 1
答案 0 :(得分:2)
这些内容在calling conventions(ABI的一部分)中定义。调用约定定义了一些内容,例如:
多年来,对于32位x86处理器(名称为cdecl
,stdcall
和fastcall
),使用了一堆略有不同的调用约定。对于64位x86处理器,基本上有only two calling conventions(一个用于Microsoft,一个用于地球上的其他人)。
在32位Windows上,printf
使用cdecl
约定。在64位Windows上,printf
使用Microsoft的64位ABI中的调用约定。
有关调用约定的更多信息可以在this answer中找到。