汇编程序为什么无法结束呢,源代码没错啊,我看了起码有10遍了,各位帮一下忙吧

msdner 2004-11-21 09:11:51
程序实现的功能就是把 a段里的数据倒序填到 b段里面,用push可以实现。


assume cs:code,ds:a,ss:b

a segment
dw 1,2,3,4,5,6,7,8
a ends

b segment
dw 0,0,0,0,0,0,0,0
b ends

code segment

start: mov ax,a
mov ds,ax
mov ax,b
mov ss,ax
mov sp,16
mov bx,0
mov cx,8
re: push [bx]
add bx,2
loop re
mov ax,4c00h
int 21h
code ends

end start
...全文
510 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunstroke 2004-11-23
  • 打赏
  • 举报
回复
大体明白了
在翻会书去

谢谢楼上!!
clumsy 2004-11-23
  • 打赏
  • 举报
回复
DS 指向 a 段, 就是 a 段偏移为 0 的那里的内容, 就是 dw 1, 2, 3, ... 中的 1
sunstroke 2004-11-23
  • 打赏
  • 举报
回复
执行mov bx,0后
push [bx]也就是把内存零地址的内容压栈?
内存为零的地方放得什么?在这个程序里


还是不太明白
楼上能在指教一下?
clumsy 2004-11-23
  • 打赏
  • 举报
回复
push [bx] 是把 bx 指向的内存处的 word 压栈. 加括号表面 bx 的内容是个内存地址, 否则的话, 就成了把 bx 的值压栈了

mov bx, 0 使 bx 指向数据段的开头, DS 又是指向 a 段的, 所以 bx 就指向 a 段的开头了
sunstroke 2004-11-23
  • 打赏
  • 举报
回复
bx怎么指到a段开头?
sunstroke 2004-11-23
  • 打赏
  • 举报
回复
push [bx]什么意思?
为什么要加括号?
msdner 2004-11-22
  • 打赏
  • 举报
回复
谢谢大家啊,回 Areslee(懒虫易水) 我的系统是windows2003sever ,我再多学一点东西,看能不能找出问题。这个帖再过两天结。
Areslee 2004-11-22
  • 打赏
  • 举报
回复
修改堆栈指针要禁止中断!!

此时,任何一个中断都会导致cs等东西压入错误堆栈,
首先
cli
mov ss,ax
mov sp,16
sti
这两句必须加上,否则会因修改顺序导致死机!!
------------------------------------------------------
这个在目前的CPU上可以不加。


其次堆栈修改后,你的堆栈空间仅8节,随便一个dos中断就会用完8字节堆栈空间,从而继续向下压栈,以致修改你的代码,运行几次自然会错!!

---------------------------------
这个绝对不会修改到楼主的代码。


相信楼主在纯DOS模式下调试不会遇到同样问题
wylpro 2004-11-22
  • 打赏
  • 举报
回复
哦!差点忘了,还有问题。。。
使用堆栈前后必须保存和恢复,否则即使你的程序运行结束也会导致以后的程序无法运行!!

另外向这样的数据访问不要用堆栈做,这种做法都是不规范的!
wylpro 2004-11-22
  • 打赏
  • 举报
回复
修改堆栈指针要禁止中断!!

此时,任何一个中断都会导致cs等东西压入错误堆栈,
首先
cli
mov ss,ax
mov sp,16
sti
这两句必须加上,否则会因修改顺序导致死机!!

其次堆栈修改后,你的堆栈空间仅8节,随便一个dos中断就会用完8字节堆栈空间,从而继续向下压栈,以致修改你的代码,运行几次自然会错!!

希望以后注意堆栈修改要规范化。
wylpro 2004-11-22
  • 打赏
  • 举报
回复
堆栈操作问题,请参照:
http://community.csdn.net/Expert/topic/3568/3568996.xml?temp=.3824884
bageer707 2004-11-22
  • 打赏
  • 举报
回复
你用Debug 调试的时候,每运行一句代码都发生一次单步中断,

发生一次单步中断,将标志寄存器入栈,cs,ip入栈

所以当运行到5,6次的时候,发生栈溢出
Areslee 2004-11-22
  • 打赏
  • 举报
回复
坎道斯你的代码不太对
mov sp,tos应该改为lea sp,tos
这个问题应该是在2k/xp下出现的吧?
Areslee 2004-11-22
  • 打赏
  • 举报
回复
那就只好请你看看当SP指向0-4的时候,
SS:FFF0-FFFF和SS:0-10的数据了
wylpro 2004-11-22
  • 打赏
  • 举报
回复
哦,不好意思,没搞清楚,您所说的是地址回绕那。
恕我孤陋寡闻,仅就我所知,地址回绕仅在UMA才会用到哈
早期的PC只有16根地址线1M内存,而段地址加偏移的寻址方法如:FFFF:000F=FFFFF最大地址。
一旦寻址大于此地址便超出物理范围,而早期的做法是直接绕回到地址00000。如FFFF:0010=00000等等。
但后来的处理器已经超出1M访问范围有多于16根的地址线,这时便有两种选择,1回绕到00000,2将内存继续向上加如:FFFF:0010=0100000。而为了保留对早期少数软件的兼容,因此添加了A20地址线选择,也就是BIOS中的A20设置,强制成0,或自动增加,如果强制第21根地址线为0则变成了地址回绕模式,反之亦然。
但是高于1M的内存只有开启保护模式才能访问,因此在进入保护模式时需要打开A20以允许其为1,而在返回实模式时如果须完全模拟早期模式,因此须再禁止A20以便地址回绕。但因为早期286的地址回绕是外部强制,所以转换速度很慢,后来将此功能集成到北桥中去了,加快了转换速度,也即FastA20。

不过很奇怪,仅就地址回绕问题所涉及的问题,好像与本贴关系并不是太大呀?因为即便地址回绕也仅是出现在开头和1M以上的大约64K范围(UMA)。如有遗误之处不吝赐教呵!
iamroc 2004-11-22
  • 打赏
  • 举报
回复
hehe
Areslee 2004-11-22
  • 打赏
  • 举报
回复
楼上的没有调试经验就不要乱说
你懂不懂什么叫地址回绕?
wylpro 2004-11-22
  • 打赏
  • 举报
回复
呵呵!要知道,x86就是x86,这是谁都必须遵守的规范(可不是我定的呦!)
您所指的“目前的cpu”?是什么cpu?
难道搂主用的就是“目前的cpu”?不要把自己特定条件下的优化强加于别人的机子之上。
这是“兼容机汇编”。
即便到目前为止很多软件厂商(尤其是游戏厂商)还在为“兼容”二字而烦恼。(当然现在的工作已不像以前那样了)
所以我只希望在写汇编时首先要遵守x86规范,然后再了解x86系列产品的各自特点。不要本末倒置。

其次也许是我比较愚笨,到现在还没想明白一个堆栈仅有8字节的程序,而且代码放在堆栈之后,在纯dos模式下是如何正确运行的!?
当然dos本身是有内部堆栈倒换的,但这个功能是有限制的,更何况搂主的堆栈直接指向数据,那么本应放在堆栈中的中断地址又放在哪里?难道要用tss?这可是实模式。即便是保护模式也不能乱用,保护模式的中断地址也并不一定就放在tss中
iamroc 2004-11-22
  • 打赏
  • 举报
回复
学习~不过很不解这个问题楼主为什么要利用堆栈进行COPY
zhengwei1984222 2004-11-22
  • 打赏
  • 举报
回复
你的源程序有错吗?
怎么我运行得很好?
加载更多回复(4)

21,459

社区成员

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

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