| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3542 人关注过本帖
标题:SP 和ESP的新旧值问题
只看楼主 加入收藏
shaoyuan
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2008-9-7
结帖率:100%
收藏
 问题点数:0 回复次数:11 
SP 和ESP的新旧值问题
为什么8086中的PUSH SP指令人栈的是该指令已修改了的SP新值,而PUSH ESP指令入栈的却是ESP在执行该指令之前的旧值???
搜索更多相关主题的帖子: ESP 
2008-10-11 09:32
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
我用DEBUG看了一下,发现不是这样的"8086中的PUSH SP指令人栈的是该指令已修改了的SP新值"
例:
C:\DOCUME~1\ADMINI~1>debug
-a
0B0E:0100 mov ax,200
0B0E:0103 mov ss,ax
0B0E:0105 mov sp,8
0B0E:0108 push sp
0B0E:0109 push sp
0B0E:010A mov ax,4c00
0B0E:010D int 21
0B0E:010F
执行后,查看:
-d 200:0
0200:0000  0E 0B 72 05 06 00 08 00-3B 45 2F 58 06 1F 8B DF
给LZ参考一下.
2008-10-11 10:20
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]shaoyuan[/un] 在 2008-10-11 09:32 的发言:[/bo]

为什么8086中的PUSH SP指令人栈的是该指令已修改了的SP新值,而PUSH ESP指令入栈的却是ESP在执行该指令之前的旧值???


貌似8086和以后的cpu不太一样
2008-10-11 17:46
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]ONEPROBLEM[/un] 在 2008-10-11 10:20 的发言:[/bo]

我用DEBUG看了一下,发现不是这样的"8086中的PUSH SP指令人栈的是该指令已修改了的SP新值"
例:
C:\DOCUME~1\ADMINI~1>debug
-a
0B0E:0100 mov ax,200
0B0E:0103 mov ss,ax
0B0E:0105 mov sp,8
0B0E:0108 push  ...


你这个没说服力吧……
2008-10-11 17:46
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
回复 4# zklhp 的帖子
栈中的数据正好是刚入栈的呀?
2008-10-12 10:02
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]ONEPROBLEM[/un] 在 2008-10-12 10:02 的发言:[/bo]

栈中的数据正好是刚入栈的呀?


他说的不是这个吧……
2008-10-12 12:07
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
列表2.1中的编码演示了怎样确定当前的CPU。它首先测试8088、8086和80286及
其之上芯片的不同之处。在8088中,一个值被推进堆栈后,堆栈指针在写入堆栈之前减
少。从80286开始,则是先写值,然后堆栈指针再减少。通过压入堆栈指针,可以检查写入
堆栈的值,来确定堆栈指针是在值写入之前还是在之后减少。如果要确定当前使用的是
80286、80386或80486,可以尝试设置80286没有使用的标志寄存器位、80286不允许使
用这些位,但80386和80486却允许。如果可以改变这些位的值,则是80386或80486。同
样的方法也可用来区别80386和80486。注意,使用66h大小的覆盖前缀去强制32位标
志寄存器被压入和弹出。这个方法是完全安全的,因为在这时,已经知道它至少是个
80386芯片。
    列表2.1
page 6o,132
;checkcpu.asm
; Determines whether the CPU in use is an 8088/8086, an 80286,  an
;80386, or an 80486.Print the CPU and return an errorlevel Of 0,
;2, 3,or4  for 8088/8086, 80286,80386,or 80486, respectively.
           .model small
            .Stack
            . data
say86      db        "8088 or 8086$"
say286 db              " 80286$"
say386 db              "80386$"
say486 db              "80486$"
            .code
            .startup
checkcpu proc
; The first step is to determine whether the chip is an 8088/8086.
;The key difference is based-on what the CPU does when it executes
;the PUSH instruction.The 8088/8086 decrements the stack
21页
; pointer first and then writes the saved value to the stack. The
; 80286, 80386, and 80486 write the value to the stack and then
; decrement the stack pointer. Thus, when SP is pushed and the
; pushed value is popped off, the value popped off equals the
; current stack pointer, unless the chip is an 8088 or 8086.
push   sp
pop ax
cmp ax,sp  ; if values are not the same,
jne is_86 , it is 8088/8086
; The second step is to detecmine whether the chip is an 80286.
; The key diffecence is the IOPL bits in the flags cegister;
; the 80386 and 80486 have them, and the 80286 does not. The
; 80286 does not let them be Set; the 80386 and 80486 do.
pushf
pop ax ; get flags in ax .
or ax,03000h ; set IOPL bits
push ax  ; stuff them back
popf , pop flags--this is where the 80286
; will put them back the way they were
pushf
pop ax ; get flags in ax
test ax,03000h ; if the IOPL bits are reset, the chip
jz iS_286 ; is an 80286
; The third Step is to determine Whether the chip iS an 80386.
; The key difference iS the alignment check bit in the flags
; register; the 80486 has one, and the 80386 does not. The 80386
; does not let you set that bit, but the 80486 does.
db 66h ; (32 bit instruction)
pushf
pop ax ; read low word of flags
and ax,00FFFh ; clear IOPL bits- -level zero
pop dx , read high word
or dx,00004h ; set alignment check bit
push dx ; push flags back
push ax
db 66h ; (32-bit instruction)
popf ; pop flags register- -this is where
; the 80386 undoes your work
db 66h ; (32-bit instruction)
pushf ; push flags back
pop ax ; read what you did
pop dx ; find out if the CPU reset the
test dx,4 ; alignment check bit
jz iS_386 ; if it did, the chip iS an 80386
is_486:
mov   dx,offset say486
mov al,4 ; errorlevel 4
jmp sayso
is_386:
mov dx, offset say386
mov al,3 ; errorlevel 3
jmp sayso
iS_286:
mov dx,offset say286
mov al,2 , errorlevel 2
22页
                      jmp     saySo
              is_86:
                  mov        dx ,offset say86
            mov        al,0           ;  errorlevel 0
              sayso:
                          push      ax        ;save errorlevel
                  mov        ah,9          ;call DOS wPite string function
                          int        21h
                          pop         ax                        ;retrieve  errorlevel
                    mov      ah , 04Ch         ;  terminate process with return code
                        int         21h
              checkcpu endp
                          end
2008-10-12 12:12
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]zklhp[/un] 在 2008-10-12 12:12 的发言:[/bo]

列表2.1中的编码演示了怎样确定当前的CPU。它首先测试8088、8086和80286及
其之上芯片的不同之处。在8088中,一个值被推进堆栈后,堆栈指针在写入堆栈之前减
少。从80286开始,则是先写值,然后堆栈指针再减少。通 ...


偶感觉楼主是这个意思
2008-10-12 12:13
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
嗯,LS很细心!
我倒没想到它竟然这么复杂~~不过,仅在8086中,用DEBUG验证了,可能是这样子的吧?
2008-10-12 13:03
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]ONEPROBLEM[/un] 在 2008-10-12 13:03 的发言:[/bo]

嗯,LS很细心!
我倒没想到它竟然这么复杂~~不过,仅在8086中,用DEBUG验证了,可能是这样子的吧?


现在上哪找8086?
2008-10-12 15:18
快速回复:SP 和ESP的新旧值问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.055290 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved