鱼C论坛

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

实验11

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

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

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

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

我先把题目抄下来:

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


应用举例:
  1. assume cs:code

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

  5. code segment

  6. start:
  7.                 mov ax,data
  8.                 mov ds,ax
  9.                 mov si,0
  10.                 call letterc
  11.                
  12.                 mov ax,4c00h
  13.                 int 21h
  14.                
  15.                
  16. letterc:
  17. .
  18. .
  19. .
  20. .
  21. code ends

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


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

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

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

  5. code segment

  6. start:
  7.                 mov ax,data
  8.                 mov ds,ax
  9.                 mov si,0
  10.                 call letterc
  11.                
  12.                 mov ax,4c00h
  13.                 int 21h
  14.                
  15.                
  16. letterc:
  17.                 cmp byte ptr ds:[si],0
  18.                 je ok
  19.                 inc si
  20.                        
  21. is_a_to_z:
  22.                 cmp byte ptr ds:[si],61h ;61h为a的ASCII码
  23.                 jb letterc
  24.                 cmp byte ptr ds:[si],7ah ;7ah为z的ASCII码
  25.                 ja letterc
  26.                        
  27. change:
  28.                 mov ax,ds:[si]
  29.                 and ax,11011111b ;变为大写字母
  30.                 mov ds:[si],ax ;覆盖原来的
  31.                
  32.                 jmp letterc
  33. ok:
  34.                 ret
  35.                
  36. code ends

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

代码如下:
  1. assume cs:code

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

  5. code segment

  6. start:
  7.                 mov ax,data
  8.                 mov ds,ax
  9.                 mov si,0
  10.                 call letterc
  11.                
  12.                 mov ax,4c00h
  13.                 int 21h
  14.                
  15.                
  16. letterc:
  17.                 mov al,ds:[si]
  18.                 cmp al,0
  19.                 je ok
  20.                 inc si
  21. is_a_to_z:
  22.                 cmp al,61h ;61h为a的ASCII码
  23.                 jb letterc
  24.                 cmp al,7ah ;7ah为z的ASCII码
  25.                 ja letterc
  26.                        
  27. change:
  28.                 dec si
  29.                 mov al,ds:[si]
  30.                 and al,11011111b ;变为大写字母
  31.                 mov ds:[si],al ;覆盖原来的

  32.                 jmp letterc
  33. ok:
  34.                 ret
  35.                
  36. code ends

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

运行效果:
未命名.jpg
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2011-2-6 22:43:05 | 显示全部楼层
楼主很有研究呀
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2011-2-13 22:16:39 | 显示全部楼层
;P自己给解决了
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2011-2-14 15:02:26 | 显示全部楼层
本帖最后由 china0008 于 2011-2-14 15:12 编辑

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

  5. code segment
  6.         begin:
  7.         mov ax,data
  8.         mov ds,ax
  9.         mov si,0
  10.         mov bx,0   ;初始化,用低8位暂存被比较值
  11.         call letterc
  12.        
  13.         mov ax,4c00h
  14.         int 21h
  15.        
  16.         letterc:
  17.         mov bl,[si]
  18.         cmp bl,00h
  19.         je ok  ;等于0就调到结束处,用于判断字符串的尾部。
  20.         inc si
  21.         cmp bl,61h
  22.         jb letterc
  23.         cmp bl,7ah
  24.         ja letterc
  25.         and bl,11011111b
  26.         mov [si-1],bl
  27.         jmp letterc       
  28. ok:
  29.         ret
  30.        
  31. code ends
  32. end begin
复制代码

调试成功

调试成功

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

同时号召广大同学向楼主学习,贴贴自己的源码,谢谢自己的学习心得。大家多交流,进步会更快。
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2012-11-12 20:19:26 | 显示全部楼层
嗯。。。。AX等于2BYTE,mov ds:[si],ax  的时候,是把0045放进去了,覆盖了原数,第三次LOOP时,检测到0,JMP到OK了。。嘿嘿
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2012-11-12 20:22:34 | 显示全部楼层
你的逻辑思维GOOD,程序看起来结构性很好,羡慕!!
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2013-9-19 10:42:18 | 显示全部楼层
随便看看,收藏丶东西,这是很好的习惯。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-10-20 01:30:21 | 显示全部楼层
mov运算操作前后操作数必须匹配
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-1 05:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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