鱼C论坛

 找回密码
 立即注册
查看: 3228|回复: 9

实验11

[复制链接]
发表于 2011-2-6 21:28:57 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 yuyuhongss 于 2011-2-6 21:35 编辑

我先把题目抄下来:

  编写一个程序,将包含任意字符,以0结尾的字符串中的小写字母转变成大写字母,描述如下:
名称:letterc
功能:将以0结尾的字符串中的小写字母转变成大写字母
参数:ds:si指向字符串首地址


应用举例:
assume cs:code

data segment
        db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment

start:
                mov ax,data
                mov ds,ax
                mov si,0
                call letterc
                
                mov ax,4c00h
                int 21h
                
                
letterc:
.
.
.
.
code ends

end start
注意需要进行转化的是字符串中的小写字母a~z,而不是其他字符。


为了易读我用了几个子程序分开,不过本质是一样的

偶的代码编译通过,运行没问题:
assume cs:code

data segment
        db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment

start:
                mov ax,data
                mov ds,ax
                mov si,0
                call letterc
                
                mov ax,4c00h
                int 21h
                
                
letterc:
                cmp byte ptr ds:[si],0
                je ok
                inc si
                        
is_a_to_z:
                cmp byte ptr ds:[si],61h ;61h为a的ASCII码
                jb letterc
                cmp byte ptr ds:[si],7ah ;7ah为z的ASCII码
                ja letterc
                        
change:
                mov ax,ds:[si]
                and ax,11011111b ;变为大写字母
                mov ds:[si],ax ;覆盖原来的
                
                jmp letterc
ok:
                ret
                
code ends

end start
不过用Debug单步执行后再查看内存发现,前两个字符可以顺利的变为大写字母,当程序运行到第三次时,也就是处理字符'g'时,竟然在执行 cmp byte ptr ds:[si],0后执行了je ok,然后就退出了'g'为什么会等于0?。我猜测是我用cmp指令时影响了标志寄存器导致的,望高手不吝赐教!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2011-2-6 22:12:26 | 显示全部楼层
终于解决~\(≧▽≦)/~啦啦啦

代码如下:
assume cs:code

data segment
        db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment

start:
                mov ax,data
                mov ds,ax
                mov si,0
                call letterc
                
                mov ax,4c00h
                int 21h
                
                
letterc:
                mov al,ds:[si]
                cmp al,0
                je ok
                inc si
is_a_to_z:
                cmp al,61h ;61h为a的ASCII码
                jb letterc
                cmp al,7ah ;7ah为z的ASCII码
                ja letterc
                        
change:
                dec si
                mov al,ds:[si]
                and al,11011111b ;变为大写字母
                mov ds:[si],al ;覆盖原来的

                jmp letterc
ok:
                ret
                
code ends

end start
变清爽了,而且就是那个si害的,后面加了一句dec si,嘿嘿,只可意会不可言传哦。。

运行效果:
未命名.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-6 22:43:05 | 显示全部楼层
楼主很有研究呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-13 22:16:39 | 显示全部楼层
;P自己给解决了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-14 15:02:26 | 显示全部楼层
本帖最后由 china0008 于 2011-2-14 15:12 编辑

也晒下我的源码。
顺便说下解题思路,首先要判断某一字节是不是需要我们修改的小写字母。这里通过比较 小写字母的ascii码来解决。这个问题解决,剩下的额就是遵循尽量不要使用对flag有影响的命令即可。
assume cs:code
data segment
        db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends

code segment
        begin:
        mov ax,data
        mov ds,ax
        mov si,0
        mov bx,0   ;初始化,用低8位暂存被比较值
        call letterc
        
        mov ax,4c00h
        int 21h
        
        letterc:
        mov bl,[si]
        cmp bl,00h
        je ok  ;等于0就调到结束处,用于判断字符串的尾部。
        inc si
        cmp bl,61h
        jb letterc
        cmp bl,7ah
        ja letterc
        and bl,11011111b
        mov [si-1],bl
        jmp letterc        
ok:
        ret
        
code ends
end begin

调试成功

调试成功

跟楼主的对比了一下,思路完全一样啊。呵呵。

同时号召广大同学向楼主学习,贴贴自己的源码,谢谢自己的学习心得。大家多交流,进步会更快。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-7-28 15:10:18 | 显示全部楼层
本帖最后由 三田学校 于 2012-7-28 15:24 编辑
我的代码如下:

assume cs:code,ds:data
data segment
db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends
code segment
start:
mov ax,data
mov ds,ax

mov ax,0b878h
mov es,ax

mov si,0
mov di,0

call letterc
mov ax,4c00h
int 21h
letterc:
mov al,[si]
cmp al,0
je exit
cmp al,'a'
jb s0
cmp al,'z'
ja s0
and al,11011111b
mov byte ptr [si],al
s0:
;显示白底黑字
mov byte ptr es:[di],al
mov byte ptr es:1[di],01110000b
inc si
add di,2
jmp short letterc
exit:
ret
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-11-12 20:19:26 | 显示全部楼层
嗯。。。。AX等于2BYTE,mov ds:[si],ax  的时候,是把0045放进去了,覆盖了原数,第三次LOOP时,检测到0,JMP到OK了。。嘿嘿
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-11-12 20:22:34 | 显示全部楼层
你的逻辑思维GOOD,程序看起来结构性很好,羡慕!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-9-19 10:42:18 | 显示全部楼层
随便看看,收藏丶东西,这是很好的习惯。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-10-20 01:30:21 | 显示全部楼层
mov运算操作前后操作数必须匹配
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-18 14:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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