鱼C论坛

 找回密码
 立即注册
查看: 2328|回复: 3

[已解决]关于进栈和处栈顺序的问题

[复制链接]
发表于 2017-9-18 21:59:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
该问题是实验10第3问显示数值的问题

这里有两个差不多一样的代码,就是子程序dtoc进栈和处栈顺序不一样的问题,如下:
(1)
  1. assume cs: code

  2. data segment

  3.         db 10 dup (0)
  4.        
  5. data ends

  6. code segment

  7. start : mov ax, 12666
  8.                 mov bx, data
  9.                 mov ds, bx
  10.                 mov si, 0
  11.                 call dtoc
  12.                
  13.                 mov dh, 8
  14.                 mov dl, 3
  15.                 mov cl, 2
  16.                 call show_str
  17.                
  18.                 mov ax, 4c00H
  19.                 int 21H
  20.                
  21. dtoc :  push ax  
  22.                 push bx
  23.                 push cx
  24.                 push dx
  25.                 push si
  26.                 push di
  27.                        
  28.                 mov di, 0
  29. d10 :   mov dx, 0
  30.                 mov bx, 10
  31.                 div bx  
  32.                
  33.                 add dx, 30H
  34.                 push dx
  35.                 inc di
  36.                 mov cx, ax
  37.                 jcxz d11
  38.                
  39.                 jmp d10
  40.                
  41. d11:         mov cx, di
  42. d12:         pop dx  
  43.                 mov [si], dl
  44.                 inc si
  45.                
  46.                 loop d12
  47.                
  48.                 mov dl, 0
  49.                 mov [si], dl
  50.                
  51.                
  52.                
  53.                        
  54. okay:         pop si
  55.                 pop di  
  56.                 pop dx
  57.                 pop cx
  58.                 pop bx
  59.                 pop ax
  60.                
  61.                 ret
  62.                        
  63. show_str:mov bx, 0
  64.                 mov ax, 0b800H
  65.                 mov es, ax
  66.                 dec dh
  67.                 mov al, dh
  68.                 mov dh, 160
  69.                 mul dh
  70.                 mov bx, ax
  71.                 mov al, dl
  72.                 mov dl, 2
  73.                 mul dl
  74.                 add bx, ax
  75.                 mov ah, cl
  76.                 mov cl, 0
  77. show :  mov al, [si]
  78.                 mov es:[bx], ax
  79.                 mov ch, [si]
  80.                 inc si
  81.                 add bx, 2
  82.                
  83.                 jcxz ok
  84.                                
  85.                 jmp show
  86. ok :        ret

  87. code ends
  88. end start
复制代码



(2)
  1. assume cs: code

  2. data segment

  3.         db 10 dup (0)
  4.        
  5. data ends

  6. code segment

  7. start : mov ax, 12666
  8.                 mov bx, data
  9.                 mov ds, bx
  10.                 mov si, 0
  11.                 call dtoc
  12.                
  13.                 mov dh, 8
  14.                 mov dl, 3
  15.                 mov cl, 2
  16.                 call show_str
  17.                
  18.                 mov ax, 4c00H
  19.                 int 21H
  20.                
  21. dtoc :  push ax  
  22.                 push bx
  23.                 push cx
  24.                 push dx
  25.                 push si
  26.                 push di
  27.                        
  28.                 mov di, 0
  29. d10 :   mov dx, 0
  30.                 mov bx, 10
  31.                 div bx  
  32.                
  33.                 add dx, 30H
  34.                 push dx
  35.                 inc di
  36.                 mov cx, ax
  37.                 jcxz d11
  38.                
  39.                 jmp d10
  40.                
  41. d11:         mov cx, di
  42. d12:         pop dx  
  43.                 mov [si], dl
  44.                 inc si
  45.                
  46.                 loop d12
  47.                
  48.                 mov dl, 0
  49.                 mov [si], dl
  50.                
  51.                
  52.                
  53.                        
  54. okay:         pop ax
  55.                 pop bx   
  56.                 pop cx
  57.                 pop dx
  58.                 pop si
  59.                 pop di
  60.                
  61.                 ret
  62.                        
  63. show_str:mov bx, 0
  64.                 mov ax, 0b800H
  65.                 mov es, ax
  66.                 dec dh
  67.                 mov al, dh
  68.                 mov dh, 160
  69.                 mul dh
  70.                 mov bx, ax
  71.                 mov al, dl
  72.                 mov dl, 2
  73.                 mul dl
  74.                 add bx, ax
  75.                 mov ah, cl
  76.                 mov cl, 0
  77. show :  mov al, [si]
  78.                 mov es:[bx], ax
  79.                 mov ch, [si]
  80.                 inc si
  81.                 add bx, 2
  82.                
  83.                 jcxz ok
  84.                                
  85.                 jmp show
  86. ok :        ret

  87. code ends
  88. end start
复制代码



这两个代码就是因为进入栈的顺序不一样就能导致得到不同的结果,前者能够显示想要的结果,而后者却是乱码,这是为什么呢?(用的masm5.0编译)
最佳答案
2017-9-19 11:51:17
若余相思 发表于 2017-9-19 10:57
第二个程序并没有将bx的值赋给si啊

你还是没说清楚为什么pop的顺序不一样,得到的结果就不一样

捕获.JPG
假设ax,bx,cx,dx,si,di分别是1,2,3,4,5,6,按照你第二个顺序取出来ax,bx,cx,dx,si,di的值就变成了6,5,4,3,2,1
从栈顶一个一个存放进去,然后从存放的最后一个数的地址反向取出。虽然你没直接mov si, bx,但是你pop si的值就是push bx进去的值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-19 10:39:03 | 显示全部楼层
先说一下FILO:first in last out,先进后出,要是先进的直接pop给先进的寄存器,那你寄存器得到的数据就和一开始你想要的不一样了。
再来看你的程序,虽然你pop出来的几个寄存器的值在显示代码段感觉用不上都是要被重新定义的,但是你忽略了一个si,你在显示代码段里没重新赋值0,所以一直用start代码段里的si,第二个程序你的si已经填入了bx的值,就不会是0了。所以得到的[si]是什么谁知道那。再来说你第一个程序,你的pop也出错了,先pop di,再pop si。
如果还有不明白的点“回复”追问哦。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-19 10:57:04 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-19 10:39
先说一下FILO:first in last out,先进后出,要是先进的直接pop给先进的寄存器,那你寄存器得到的数据就和 ...

第二个程序并没有将bx的值赋给si啊

你还是没说清楚为什么pop的顺序不一样,得到的结果就不一样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-19 11:51:17 | 显示全部楼层    本楼为最佳答案   
若余相思 发表于 2017-9-19 10:57
第二个程序并没有将bx的值赋给si啊

你还是没说清楚为什么pop的顺序不一样,得到的结果就不一样

捕获.JPG
假设ax,bx,cx,dx,si,di分别是1,2,3,4,5,6,按照你第二个顺序取出来ax,bx,cx,dx,si,di的值就变成了6,5,4,3,2,1
从栈顶一个一个存放进去,然后从存放的最后一个数的地址反向取出。虽然你没直接mov si, bx,但是你pop si的值就是push bx进去的值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 05:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表