注册 登录
编程论坛 汇编论坛

初学小问题,cx的值如何又变成4的,有程序

luohua2007 发布于 2007-05-22 17:56, 1391 次点击

问题:把段内每个单词的改为大写字母,下面是正确的程序,只是我不理解,还请大家指点一下,谢谢了
datasg segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov sp,16
mov bx,0
mov cx,4
s: ;外循环
mov dx,cx//这个DX的值是一直变动的把,开始等于4,下来等于3,2,1,0
mov si,0
mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢,
s0: ;内循环
mov al,[bx+si]
and al,11011111b//改写成了大写字母
mov [bx+si],al
inc si
loop s0
add bx,16
mov cx,dx//是这个吗。DX的值不可能一直等于4把
loop s
mov ax,4c00h
int 21h
codesg ends
end start

[此贴子已经被作者于2007-5-22 17:57:30编辑过]

10 回复
#2
菜鸟上路2007-05-22 19:23

汇编不区分大小写
datasg segment
db '1. display '
db '2. brows '
db '3. replace '
db '4. modify '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov sp,16
mov bx,0
mov cx,4
s: ;外循环
mov dx,cx//这个DX的值是一直变动的把,开始等于4,下来还是等于4,DX的值一直没变呀
mov si,0
mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢, 是MOV CX, DX
s0: ;内循环
mov al,[bx+si]
and al,11011111b//改写成了大写字母
mov [bx+si],al
inc si
loop s0
add bx,16
mov cx,dx//是这个,DX一直等于4
loop s
mov ax,4c00h
int 21h
codesg ends
end start

#3
luohua20072007-05-22 19:45
[QUOTE]汇编不区分大小写
[/QUOTE]
我主要的问题是cx的值如何又变成4的,
至于大小写就无所谓了,给指点一下把

[此贴子已经被作者于2007-5-22 19:46:45编辑过]

#4
菜鸟上路2007-05-22 19:54
如果用LOOP的话,硬件会自动给CX减1,然后跟0比较,相当于dec cx, cmp cx,0 jae s
#5
luohua20072007-05-22 22:59
2位斑竹啊,你们咋就不看我的问题呢,我是想问,那个 mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢,

请指点一下把
#6
guancracker2007-05-23 00:56

程序写错了吧。这个程序只是把datasg段中每个单词的第一个字母改为大写字母。

datasg segment
db '1. display ' //你这里应该是16个字节吧
db '2. brows '
db '3. replace '
db '4. modify '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov sp,16
mov bx,0
mov cx,4
s: ;外循环
mov dx,cx
mov si,0
mov cx,4 //这个4 是每一行(例如'1. display ')的前四个数据循环4次
s0: ;内循环
mov al,[bx+si] //你这里实际就是 mov al,ds:[0]
and al,11011111b// 难道你也想把如'1. display '中的 1. 改写成了大写字母吗?其实你只把d 改成大写 ; 1. 只是数据改变了。
mov [bx+si],al
inc si
loop s0
add bx,16 //换一行。
mov cx,dx
loop s
mov ax,4c00h
int 21h
codesg ends
end start

不知道对不对,献丑了。

[此贴子已经被作者于2007-5-23 1:30:23编辑过]

#7
luohua20072007-05-23 01:29
[QUOTE]程序写错了吧。这个程序只是把datasg段中每个单词的前四个字母改为大写字母[/QUOTE]
你说的对,这个程序原本的意思就是要把datasg段中每个单词的前四个字母改为大写字母就可以了,
我只是不明白那个 mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢

这才是我不明白的地方啊
#8
guancracker2007-05-23 01:33
不好意思,刚才没注意。看错了。
只是把datasg段中每个单词的第一个字母改为大写字母
#9
guancracker2007-05-23 01:43

那照你的意思我改一下 下面的程序是修改每一行的前4个字母

datasg segment
db 'display ' //这里是16个字节
db 'brows '
db 'replace '
db 'modify '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov sp,16 //不用这个了,没用到栈
mov bx,0
mov cx,4
s: ;外循环
mov dx,cx//这个DX的值是一直变动的把,开始等于4,下来等于3,2,1,0
(这是对的啊。因为执行一次loop s CX-1)

mov si,0
mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢,(mov cx,4是这个让它又变成4 因为它要修改的是前4个字母 )
s0: ;内循环
mov al,[bx+si]
and al,11011111b//改写成了大写字母
mov [bx+si],al
inc si
loop s0
add bx,16
mov cx,dx//是这个吗。DX的值不可能一直等于4把 (DX的值当然不可能一直等于4了。因为 执行一次loop s
CX-1 回到s: ;外循环mov dx,cx DX不就等于3 了吗)
loop s
mov ax,4c00h
int 21h
codesg ends
end start


[此贴子已经被作者于2007-5-23 1:49:28编辑过]

#10
luohua20072007-05-23 10:04
[QUOTE]mov cx,4 //就是这句我不明白,一层内循环完了后,CX因该就变成0了,当第2,3,4层外循环到来时候,是哪个语句让它又变成4的呢,(mov cx,4是这个让它又变成4 因为它要修改的是前4个字母 )
[/QUOTE]
非常感谢,问题明白了,可能是我的描述有问题,这才是我想问的问题,
让大家费心了,非常谢谢
#11
Pants2007-05-23 10:19

datasg segment
db 'display '
db 'brows '
db 'replace '
db 'modify '
datasg ends
codesg segment
start:
mov ax,datasg
mov ds,ax
mov sp,16
mov bx,0
mov cx,4
s: ;外循环
mov dx,cx ;保存外循环的循环次数,相当于入栈,dx相当于栈
mov si,0
mov cx,4 ;设置内循环的循环次数
s0: ;内循环
mov al,[bx+si]
and al,11011111b
mov [bx+si],al
inc si
loop s0
add bx,16
mov cx,dx ;调出外循环的循环次数,相当于出栈
loop s
mov ax,4c00h
int 21h
codesg ends
end start

由于内外循环都要用到cx,因此在内循环开始之前,要先把外循环的cx保存起来,内循环结束后再恢复。
一般推荐用栈或内存来保存,最好不要用寄存器来保存。

1