|
主题 : : 检测点9.3疑惑 [待解决] |
回复[ 46次 ]
点击[ 2210次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2007-11-29 11:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-11-29 11:23 |
补全程序,利用loop指令,实现在内存2000段中查找第一个值为0的byte, 找到后,将它的偏移地址存储在dx中
assume cs:code
code segment
start:mov ax, 2000h
mov ds, ax
mov bx, 0
s:mov cl, [bx]
mov ch, 0
____________ 感觉这个空好像不要添什么东西了啊
inc bx
loop s
ok:dec bx
mov dx, bx
mov ax, 4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2007-11-29 14:28 ]
[引用]
[回复]
[ top ] | |
荣誉值:33
信誉值:0
注册日期:2007-07-10 11:31 |
|
|
|
|
|
[第2楼]
[ 回复时间:2007-11-29 16:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:19
信誉值:0
注册日期:2007-07-05 17:25 |
这个题和LOOP指令的执行原理有关系。
loop指令是先把CX寄存器的值减1然后再判断是否是0。
楼主现在你在看看题中应该填什么? | | |
|
|
|
|
[第3楼]
[ 回复时间:2007-12-01 16:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-11-13 15:53 |
|
|
|
|
|
[第4楼]
[ 回复时间:2007-12-03 16:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2007-11-29 11:23 |
|
|
|
|
|
[第5楼]
[ 回复时间:2008-03-31 11:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2008-03-10 10:19 |
我说呢,怎么cx都为0了,loop s 还发挥作用! | | |
|
|
|
|
[第6楼]
[ 回复时间:2008-04-17 14:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-05 19:14 |
|
|
|
|
|
[第7楼]
[ 回复时间:2008-04-19 16:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-05 19:14 |
|
|
|
|
|
[第8楼]
[ 回复时间:2008-04-30 18:39 ]
[引用]
[回复]
[ top ] | |
荣誉值:12
信誉值:0
注册日期:2008-04-05 17:12 |
应该填jcxz ok 但是ok:dec bx
为什么要减去一呢? | | |
|
|
|
|
[第9楼]
[ 回复时间:2008-05-04 23:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-15 00:14 |
此题的用以是要你理解Loop,所以才设置 ok:dec bx
这样的话,就不能用jcxz ok了。 | | |
|
|
|
|
[第10楼]
[ 回复时间:2008-05-21 14:36 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:16
注册日期:2008-03-17 20:21 |
|
|
|
|
|
[第11楼]
[ 回复时间:2008-05-26 18:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45 |
|
|
|
|
|
[第12楼]
[ 回复时间:2009-02-22 15:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-02-19 10:20 |
刚刚开始的时候我填的是loop ok ,然后cx=0了 ,向下面执行 ,可是了又开始循环了 而且是死循环 看了楼主的 ,茅塞顿开啊 | | |
|
|
|
|
[第13楼]
[ 回复时间:2009-05-05 10:01 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-24 09:00 |
assume cs:code
code segment
start:mov ax, 2000h
mov ds, ax
mov bx, 0
s:mov cl, [bx] ;如2000:0003内存单元中为0 ,cl=0
mov ch, 0
inc cx ;cx=0001
inc bx ;加1 2000:0004
loop s ;cx=cx-1
ok:dec bx ;上面加了1这里就减1 bx=0003
mov dx, bx ;DS:偏移地址 dx=0003
mov ax, 4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第14楼]
[ 回复时间:2009-05-15 14:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-22 12:29 |
|
|
|
|
|
[第15楼]
[ 回复时间:2009-05-15 14:47 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-04-22 12:29 |
填INC CX 好像也不行吧~~ 在到达 LOOP S前 CX永远不会是 0 所以又是个死循环啊~~ 这个空什么不填 就能完成这个 功能 ~~ 或者填写无关紧要的 大家看行不
例如 MOV SI,0 MOV DI,0 之类的~~ | | |
|
|
|
|
[第16楼]
[ 回复时间:2009-05-16 22:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-12-25 16:57 |
在段地址为2000中内存中都是0000不管是什么,只要使mov dx,bx就是0啊
例题出的不行,应该找其他的段地址试试啊 | | |
|
|
|
|
[第17楼]
[ 回复时间:2009-05-21 19:27 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-13 22:27 |
填add al,1正解。
段地址2000后面的内存好多是0.
可以先用e 2000:0改一两个内存单元的值。
然后再测试.虽然麻烦了点儿. | | |
|
|
|
|
[第18楼]
[ 回复时间:2009-05-21 21:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-06 21:40 |
假设第一次执行,cl=((ds)*16+(bx))=01 的话
空格处不填INC AX,1 那么,当执行到LOOP命令处时,(cx)=(cx)-1 就会直接跳出循环,往下执行了。 | | |
|
|
|
|
[第19楼]
[ 回复时间:2009-05-27 14:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2007-12-08 14:22 |
我今天也碰到这个问题,想了想,LOOP中ECX不能为0 运行到LOOP X 它是先 -1 再判断是否=0 如果直接将ECX设成0 ECX - 1 = FFFFFFFFH = 4294967296次 CX - 1 = FFFFH = 65536次... 上面 即使CX = 0 还要 INC +1处理之后才可以跳出循环 | | |
|
|
|
|
[第20楼]
[ 回复时间:2009-06-26 11:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:10
注册日期:2009-06-18 18:17 |
这个题考到我了
1\ loop执行原理,不理解透
2\ 不看第3楼 xkxpiao 说的,我不会想一 inc cx.因为刚讲了 jcxz.理所当然想要加是这跟这个有关的.
这样看来,自己很不合格,学习态度要端正.从今天起放慢进度,1章用2-3天认真仔细学,多实验比较,可能这样才能学得更多 | | |
|
|
|
|
[第21楼]
[ 回复时间:2009-06-26 20:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2008-11-29 19:08 |
晕了,感觉填这个INC CX也是多余,没什么用,JCXZ OK感觉合理点 | | |
|
|
|
|
[第22楼]
[ 回复时间:2009-07-06 07:17 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-07-01 22:00 |
之前也没想出来,就写了个 nop 上去。
后来 debug 的时候发现 cx 变成 ffff 才想到 loop 的原理。 | | |
|
|
|
|
[第23楼]
[ 回复时间:2009-07-29 13:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:3
注册日期:2009-06-08 15:13 |
add cx,1
或者
inc cx
为什么为什么要这样呢,当mov cl,[bx] mov ch,0查找到字节中为0的时候,我们希望他去执行0k处之指令,但是如果这里填转移指令,那么bx将减1,得不到真实偏移量,唯一的方法是执行完循环中的程序,inc bx(以便后来减一)让他自动跳出循环,怎样跳出循环,loop指令怎么执行,cx=cx-1 if(cx==0)跳出循环,但是你刚才cx已经为0
,如果减一,按补码形式,不可能是0,所以只有先加1了,然后让loop执行减1等于0跳出循环 | | |
|
|
|
|
[第24楼]
[ 回复时间:2009-08-09 21:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2009-07-29 23:03 |
楼上正解,是填 inc cx
刚开始我也觉得不用填什么,后来想明白loop指令的原理,才发现cx还得加1,不然cx为0,再减1成ffffh陷入另一个循环中... | | |
|
|
|
|
[第25楼]
[ 回复时间:2009-08-09 22:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2009-07-29 23:03 |
补充一句,Ok行的那个标号Ok确实多余,容易误导,如果直接dec bx可能更容易明白。
可能这正是王爽老师的用意吧,需要仔细思考loop的执行原理才能找出答案 呵呵 | | |
|
|
|
|
[第26楼]
[ 回复时间:2009-08-13 11:29 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
没有错是inc cx 我经过调试。假设把2000:0 设为1,2,3,4,5等
然后开始调试。看看结果。 | | |
|
|
|
|
[第27楼]
[ 回复时间:2009-08-24 21:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-08-24 21:15 |
|
|
|
|
|
[第28楼]
[ 回复时间:2009-09-06 18:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-07-16 11:29 |
|
|
|
|
|
[第29楼]
[ 回复时间:2009-09-13 14:14 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:4
注册日期:2009-07-29 23:59 |
用“INC CX”是可以得到正确的结果!但是个人想法是即既然程序中出现了标号“OK”,那就一定要想出一条与这个标号“OK”相呼应的转移指令来!那就是“JCXZ [OK+1]”,“OK:DEC BX”这条指令为1个字节,所以用“OK+1”跳过“OK:DEC BX”这条指令!我是初学者,各位大侠不要见笑呀! | | |
|
|
|
|
[第30楼]
[ 回复时间:2009-10-25 20:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-20 21:58 |
|
|
|
|
|
[第31楼]
[ 回复时间:2009-10-26 21:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-19 20:15 |
29楼 正解不过填“JCXZ [OK+1]” DEC BX这个程序就一点用也没用了,也显不出LOOP的特性,填INC CX虽然OK标号不起作用但能显示出这一章的重点。我 觉得是INC CX 小弟愚见 | | |
|
|
|
|
[第32楼]
[ 回复时间:2009-11-25 12:27 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:0
注册日期:2009-10-18 04:41 |
inc cx是正解啊,我学过C其实早就能理解LOOP指令,可是我就是没明白他上面都把CX清零了还怎么能循环,这个题要从两个方面去理解
(1)当内存时面遇到有零的时候CX被清零了,这时如果没有INC CX那么,就相当于0-1 CX得到的是FFFF很明显不能得到正确的结果,但是当我们在那里加一句INC CX时就不同了,因为当他第一个找到为零的结果的时候CL [BX] CH,0这两句把CX清零了,也就是说我们已经找到了第一个为零的结果了,这时候我们要退出循环,怎么样退出循环,就要保证CX 为零 而LOOP S 是先CX-1 结果为零就退出,那么我们就要相办法让CX 为零,所以先让已被 CL [BX] CH,0清零的CX 加上1让LOOP S执行后刚好为零这样就刚好找到了退出循环,至于为什么要 DEC BX我想这也是一目了然的,因为前面多加了一个INC BX
(2)当内存里面不是零的时候,(这个很重要)不为零的时候很明显,CL,[BX]将得到不为零的结果,也就是说CX 会得到一个值 你不要管这个值的大小,然后INC CX这句只不过是在他找到不为零的值上面加上了1 记住这时候CX是有值的也就是这个循环不会退出会一直下去直到遇到有零的然后 不管CX里面得到内存里面多大的值他都会因为遇到内存里面有零的值把他清零,所以就回到(1) | | |
|
|
|
|
[第33楼]
[ 回复时间:2009-12-06 19:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-20 21:58 |
我感觉王爽老师这道检测题真是经典恰恰也体现汇编语言的灵活多变性,个人的思路不一样答案也就不一样,只有这样才能体现自己的风格总之条条大路通罗马呵呵呵。这道题至少可以填5句指令而最后结果相同。 | | |
|
|
|
|
[第34楼]
[ 回复时间:2009-12-08 18:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2009-10-30 15:46 |
|
|
|
|
|
[第35楼]
[ 回复时间:2011-07-01 09:51 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
jczx ok+1是不正确的。
假设2000:0 01 02 03 - - - -- - --
执行mov cl,[bx]
mov ch,0 此时 cx=1
jcxz bx+1 不作执行
inc bx
loop s cx-1=0跳出执行 就会导致找不到2000的第一个为零的字节,就程序就退出了。 | | |
|
|
|
|
[第36楼]
[ 回复时间:2011-07-21 10:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-05-08 00:01 |
|
|
|
|
|
[第37楼]
[ 回复时间:2011-07-29 15:03 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-06-18 10:01 |
|
|
|
|
|
[第38楼]
[ 回复时间:2011-07-29 15:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-06-18 10:01 |
|
|
|
|
|
[第39楼]
[ 回复时间:2011-09-27 18:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-08-18 06:18 |
CPU执行LOOP的时候要进行两步操作
1,(cx)=(cx)-1
2, 判断CX中的值,不为零则转至标号处执行程序,如果为零则向下执行
------------------------------------------------------
如果偏移地址bx中数据为零,则执行完
mov cl,[bx]
mov ch,0
cx为0 那么 在执行到LOOP的时候
(cx)=(cx)-1
CX就等于FFFF了。 所以要想让着道题正确执行则要将CX加1 | | |
|
|
|
|
[第40楼]
[ 回复时间:2011-10-18 10:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-10-13 17:01 |
35楼的兄弟说的对,JCXZ OK+1 不行得。还有不能是JCXZ [OK+1],只可能是JCXZ OK+1。 | | |
|
|
|
|
[第41楼]
[ 回复时间:2011-11-30 11:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:13
注册日期:2011-07-13 08:38 |
inc cx是正解,如果不加上这一句,那么当cx=0时,再遇到loop指令,此时cx=cx-1=-1,不满足循环结束的条件,就难以定位第一个值为0的字节。 | | |
|
|
|
|
[第42楼]
[ 回复时间:2013-05-19 11:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2013-04-18 10:09 |
assume cs:codesg
codesg segment
start:mov ax,2000h
mov ds,ax
mov bx,0
s:mov cl,[bx]
mov ch,0h
jcxz ok
inc bx
jmp short s
ok:mov dx,bx
mov ax,4c00h
int 21h
codesg ends
end start | | |
|
|
|
|
[第43楼]
[ 回复时间:2013-05-22 19:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2013-05-22 12:56 |
总结了下。
1.认为不缺内容的,犯错的原因是把Loop和C语言的循环功能混淆了,C语言中确实只要完成循环体中的内容就好了;
2.汇编中完成循环功能的模板是,CX的赋值在LOOP外,而这里CX出现在了LOOP中,必然要格外考虑;
3.0-1=FFFFH,不是-1,当然-1的补码形式FFFFH;
分析循环的一个方法:从成立条件出发,这里成立的条件就是CX=0,由此出发,逐条指令进行分析,由于,汇编语言不是高级语言.所以分析是要从汇编指令和机器码两个角度一步一步对应好. | | |
|
|
|
|
[第44楼]
[ 回复时间:2013-05-22 19:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2013-05-22 12:56 |
汇编指令即数据,数据也可为汇编指令,所以理解汇编指令时会出现与程序想法冲突的情况. | | |
|
|
|
|
[第45楼]
[ 回复时间:2014-05-11 23:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2012-12-22 18:01 |
我觉得答案是inc cx . ok标签是用来迷惑思路的。分析:如果循环里如果没有字节空间里是01h,那么不可能跳出循环(先不考虑填空的部分)。然后如果在00h字节之前有一个01h,那么这里跳出时,bx正好是需要的值,再减1就错了。如果01h字节之后没有00h,那么bx也不是需要的值。而且cx=00h时,为了能跳出循环,先自加1,是可行的,因为用了loop指令。所以在填空处使用inc cx,既可以找到00h,也避免了01h, 00h 这种情况出现错误。还满足了 (1至ffh), 00h 这种情况的出现。 | | |
|
|
|
|
[第46楼]
[ 回复时间:2020-05-10 17:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2020-05-06 18:39 |
|