为什么push段寄存器ESP减4?

cwanter 2003-09-16 02:06:37
80x86 32位CPU~
...全文
718 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
W32API 2003-09-18
  • 打赏
  • 举报
回复
哦,这样那你应该知道单条指令的执行流程与操作系统无关。
既然你知道,那你要什么实际的?
另外我想声明的是,
INTEL 的模式的精通程度我恐怕并不是那么在意。
如打扰你老兄的雅兴。。。
真是有点不好意思了
BraveHeart2222 2003-09-18
  • 打赏
  • 举报
回复
我倒!还用得着你上面的资料吗,学过汇编的就知道执行堆栈操作指令时,栈指针寄存器的内部动作,还有,不怕老兄不高兴,对什么实模式、保护模式、V86模式,恐怕不比你差
W32API 2003-09-18
  • 打赏
  • 举报
回复
TO:BraveHeart2222(勇敢的心2222)
不清楚你所说的实际点的是什么。
根据 INTEL 的资料,
他并没有向操作系统提供任何途径去更改指令执行的流程。
这个是对你的回答。

以下是 INTEL 公开的堆栈指令执行的流程:
PUSH—Push Word or Doubleword Onto the Stack (Continued)
Operation:
IF StackAddrSize = 32
THEN
IF OperandSize = 32
THEN
ESP ← ESP - 4;
SS:ESP ← SRC; (* push doubleword *)
ELSE (* OperandSize = 16*)
ESP ← ESP - 2;
SS:ESP ← SRC; (* push word *)
FI;
ELSE (* StackAddrSize = 16*)
IF OperandSize = 16
THEN
SP ← SP - 2;
SS:SP ← SRC; (* push word *)
ELSE (* OperandSize = 32*)
SP ← SP - 4;
SS:SP ← SRC; (* push doubleword *)
FI;
FI;

Flags Affected:None.

不清楚你对 CPU 的运行模式是否有了解,
你可以先去看看 V86 模式的情况。
这也是我之所以问渔夫同志是在什么情况下面。
BraveHeart2222 2003-09-17
  • 打赏
  • 举报
回复
楼上的怎么老是故着高深:
“指令的执行流程是 INTEL CPU 的事情,我没有资料显示 INTEL 提供手段可以使操作系统控制指令的运行流程。”
怎么又扯到什么指令的运行流程去了,来点实际的好吗????
W32API 2003-09-17
  • 打赏
  • 举报
回复
PUSH—Push Word or Doubleword Onto the Stack (Continued)
Operation:
IF StackAddrSize = 32
THEN
IF OperandSize = 32
THEN
ESP ← ESP - 4;
SS:ESP ← SRC; (* push doubleword *)
ELSE (* OperandSize = 16*)
ESP ← ESP - 2;
SS:ESP ← SRC; (* push word *)
FI;
ELSE (* StackAddrSize = 16*)
IF OperandSize = 16
THEN
SP ← SP - 2;
SS:SP ← SRC; (* push word *)
ELSE (* OperandSize = 32*)
SP ← SP - 4;
SS:SP ← SRC; (* push doubleword *)
FI;
FI;

Flags Affected:None.

W32API 2003-09-17
  • 打赏
  • 举报
回复
?跟平台有关系??指操作系统吗?
指令的执行流程是 INTEL CPU 的事情,
我没有资料显示 INTEL 提供手段可以使操作系统控制指令的运行流程。

INTEL 的原话。。。
The segment registers (CS, DS, SS, ES, FS, and GS) hold 16-bit segment selectors.虽然我有资料显示从 386 开始这些寄存器前有隐藏的数据。
但是 INTEL 没有明确公开。并且这些不会在 PUSH 时入栈。

PUSH—Push Word or Doubleword Onto the Stack (Continued)
Operation:
IF StackAddrSize = 32
THEN
IF OperandSize = 32
THEN
ESP ← ESP − 4;
SS:ESP ← SRC; (* push doubleword *)
ELSE (* OperandSize = 16*)
ESP ← ESP − 2;
SS:ESP ← SRC; (* push word *)
FI;
ELSE (* StackAddrSize = 16*)
IF OperandSize = 16
THEN
SP ← SP − 2;
SS:SP ← SRC; (* push word *)
ELSE (* OperandSize = 32*)
SP ← SP − 4;
SS:SP ← SRC; (* push doubleword *)
FI;
FI;

Flags Affected:None.

Areslee 2003-09-17
  • 打赏
  • 举报
回复
32位代码在PUSH/POP段寄存器时都是用4个字节
BraveHeart2222 2003-09-17
  • 打赏
  • 举报
回复
看了一下它的反汇编代码,没有任何奇怪之处,执行时也只是将FS或DS的16位值进四个字节的低字,我想这是平台的关系,若是在纯DOS下的话应该是正常的减2而不是减4,不过我没试。
BraveHeart2222 2003-09-17
  • 打赏
  • 举报
回复
我上面错了,FS也是16位的,再想想。
Areslee 2003-09-17
  • 打赏
  • 举报
回复
李诚版主不是说得已经很清楚了吗
再重复一遍:
32位模式下段寄存器出入栈都是用4个字节
cwanter 2003-09-16
  • 打赏
  • 举报
回复
你把FS改为CS或ds还是减4~我本来是想用CS的,为了实验就改为fs了,你可以用任何一个段寄存器试试~
BraveHeart2222 2003-09-16
  • 打赏
  • 举报
回复
这段代码好象没什么意义,楼主是吗?
BraveHeart2222 2003-09-16
  • 打赏
  • 举报
回复
cs,ds是16位的
BraveHeart2222 2003-09-16
  • 打赏
  • 举报
回复
楼主的代码很有意思,好象是要修改异常处理链的地址(因为FS:0是指向异常处理链的)
int main(int argc, char* argv[])
{
short wCs; //这是局部变量,在栈中是紧挨返回地址的
_asm
{
push ax; //两个字节进栈
push fs; //四个字节进栈
pop ax; //弹出栈顶的两个字节
mov wCs,ax; //局部变量wCs保存FS的低字
pop ax; //再次弹出栈顶的两个字节,此时AX为FS的高字
//进了6个字节,只弹出四个字节
} //遇到"}"会有什么动作呢??我要查查

return 0; //函数的返回值一般是在AX中的
}
cwanter 2003-09-16
  • 打赏
  • 举报
回复
cs,ds呢?应该是16位吧?
BraveHeart2222 2003-09-16
  • 打赏
  • 举报
回复
因为FS寄存器是32位(四个字节)的,所以esp要减4
cwanter 2003-09-16
  • 打赏
  • 举报
回复
int main(int argc, char* argv[])
{
short wCs;
_asm
{
push ax;
push fs; //段寄存器esp就减4
pop ax;
mov wCs,ax;
pop ax;
}

return 0;
}
W32API 2003-09-16
  • 打赏
  • 举报
回复
什么情况下面?

21,493

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧