为什么我的筹码很奇怪? [英] Why is my stack odd?

查看:61
本文介绍了为什么我的筹码很奇怪?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简短的程序....

Here's a short program....

int main()
{
	_asm
	{
		push al;
		pop al;
		pop al;
	};
    return 0;
}



哪个做得不多但是有效。但我认为不应该这样做,因为我将'al'推到堆叠上然后尝试将其拉出两次,因此堆叠起来。



似乎push实际上是将堆栈指针移动4个字节,而pop只是将它移回2,但是寄存器应该是一个字节,16bit的下半部分。发生了什么事?



我尝试了什么:



嗯,我试着在脑子里想了一下,但没有用。


which doesn't do much but it works. But I don't think it should, as I push 'al' onto the stack then try and pull it off twice, hence knackered stack.

It seems that the push is actually moving the stack pointer by 4 bytes, whereas the pop is only moving it back by 2, yet the register is supposed to be a single byte, the lower half of a 16bit thing. What's going on?

What I have tried:

Well, I tried thinking about it in my head for a bit, but it didn't help.

推荐答案

Quote:

看起来推送实际上是将堆栈指针移动4个字节,而pop只是将它移回2,但寄存器应该是一个字节,下半部分是16位的东西。发生了什么事?

It seems that the push is actually moving the stack pointer by 4 bytes, whereas the pop is only moving it back by 2, yet the register is supposed to be a single byte, the lower half of a 16bit thing. What's going on?



al register是1字节,所以 push pop 正在移动堆栈指针 1个字节

根据设计,堆栈指针会根据您选择的寄存器大小移动。你的职责是使所有堆栈操作保持一致。



使用调试器可以看到究竟发生了什么。

Debugger - 维基百科,免费的百科全书 [ ^ ]



掌握Visual Studio 2010中的调试 - 初学者指南 [ ^ ]

使用Visual Studio 2010进行基本调试 - YouTube [ ^ ]


al register is 1 byte, so push and pop are moving stack pointer 1 byte.
By design, stack pointer move accordingly with size of register you selected. Your duty is to make all stack operations consistent.

Use debugger to be able to see what happen exactly.
Debugger - Wikipedia, the free encyclopedia[^]

Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
Basic Debugging with Visual Studio 2010 - YouTube[^]


从空堆栈中弹出值不一定做任何坏,它只是检索一个一个地址的值,并递减指针。只有当该地址在进程的内存空间之外时才会出现错误。从理论上讲,你可能会从返回0中得到一个问题,因为它应该使用堆栈来获取退出地址并且你已经从堆栈中删除了它,但很可能你的编译器没有使用机器代码返回但是通过系统调用终止进程 - 我已经看到它根据编译器编写器的首选项完成两种方式。



至于大小,当你在机器代码中添加或删除堆栈中的任何项目,您使用相同的空间量 - 机器字,可能是16位,32位或64位。如果没有,那么堆栈最终会出现在奇数地址,这是出于技术原因的一个坏主意。

我很惊讶push al工作 - 它生成的机器代码几乎可以肯定是推动斧头以避免奇怪的地址。
Popping the value off an empty stack doesn't necessarily do anything "bad", it just retrieves a value at an address, and decrements the pointer. It's only if that address is outside the memory space for the process that you will get an error. In theory, you could get a problem from the "return 0" as it should be using the stack to fetch the exit address and you have removed that from the stack, but the chances are that your compiler doesn't use the machine code "return" but terminates the process via a system call instead - I've seen it done both ways depending on the compiler writers preferences.

As for the size, when you add or remove any item from the stack in machine code, you use the same amount of space - a machine word, which is likely to be 16, 32, or 64 bits. If it didn't, then the stack would end up at odd addresses which is a bad idea for technical reasons.
I'm surprised that "push al" worked at all - the machine code it generates will almost certainly be "push ax" to avoid odd addresses.


这篇关于为什么我的筹码很奇怪?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆