在递归函数中使用 pushad 时,堆栈指针似乎没有增加
Stack pointer does not seem to increase when using pushad in recursive function
int x = 5;
void foo()
{
long unsigned r[8];
memset(&r, 0, sizeof(long unsigned) * 8);
__asm {
pushad;
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
}
printf("Register values: \n");
printf("eax: %lu\n", r[0]);
printf("ecx: %lu\n", r[1]);
printf("edx: %lu\n", r[2]);
printf("ebx: %lu\n", r[3]);
printf("esp: %lu\n", r[4]);
printf("ebp: %lu\n", r[5]);
printf("esi: %lu\n", r[6]);
printf("edi: %lu\n", r[7]);
if (--x) { foo(); }
}
int main()
{
foo();
return 0;
}
我刚刚了解了 pushad/pusha 操作,正在尝试查看 GPR 的变化情况。但是,除了 r[0] 之外,我似乎得到了所有这些的 0 打印,它为每个 foo() 调用打印出按 44 递减的数字。对吗?
据我所知,每次调用新函数时 esp 寄存器不应该移动吗?
这并不完全符合您的要求:
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
这实际上并没有计算数组中每个 LONG 的地址 r
并将值弹出到该位置。就像写:
pop [r+7];
pop [r+6];
pop [r+5];
pop [r+4];
pop [r+3];
pop [r+2];
pop [r+1];
pop [r+0];
内联程序集不考虑数组数据元素的大小。将值添加到数组的基数递增,就像索引以字节为单位一样。
可能更清楚发生了什么。 r
将是数组的基地址(因为它在堆栈上,所以相对于 ebp
)。 r+0
是第一个 BYTE 的位置,r+1
是第二个 BYTE 的位置等。您需要计算并计算每个 LONG 的索引。所以它应该看起来像:
pop r[28];
pop r[24];
pop r[20];
pop r[16];
pop r[12];
pop r[8];
pop r[4];
pop r[0];
int x = 5;
void foo()
{
long unsigned r[8];
memset(&r, 0, sizeof(long unsigned) * 8);
__asm {
pushad;
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
}
printf("Register values: \n");
printf("eax: %lu\n", r[0]);
printf("ecx: %lu\n", r[1]);
printf("edx: %lu\n", r[2]);
printf("ebx: %lu\n", r[3]);
printf("esp: %lu\n", r[4]);
printf("ebp: %lu\n", r[5]);
printf("esi: %lu\n", r[6]);
printf("edi: %lu\n", r[7]);
if (--x) { foo(); }
}
int main()
{
foo();
return 0;
}
我刚刚了解了 pushad/pusha 操作,正在尝试查看 GPR 的变化情况。但是,除了 r[0] 之外,我似乎得到了所有这些的 0 打印,它为每个 foo() 调用打印出按 44 递减的数字。对吗?
据我所知,每次调用新函数时 esp 寄存器不应该移动吗?
这并不完全符合您的要求:
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
这实际上并没有计算数组中每个 LONG 的地址 r
并将值弹出到该位置。就像写:
pop [r+7];
pop [r+6];
pop [r+5];
pop [r+4];
pop [r+3];
pop [r+2];
pop [r+1];
pop [r+0];
内联程序集不考虑数组数据元素的大小。将值添加到数组的基数递增,就像索引以字节为单位一样。
可能更清楚发生了什么。 r
将是数组的基地址(因为它在堆栈上,所以相对于 ebp
)。 r+0
是第一个 BYTE 的位置,r+1
是第二个 BYTE 的位置等。您需要计算并计算每个 LONG 的索引。所以它应该看起来像:
pop r[28];
pop r[24];
pop r[20];
pop r[16];
pop r[12];
pop r[8];
pop r[4];
pop r[0];