鱼C论坛

 找回密码
 立即注册
查看: 3758|回复: 6

[汇编作业] 实验10 编写子程序

[复制链接]
发表于 2020-4-11 16:05:58 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 流风逸雪 于 2020-4-11 16:14 编辑

1.显示字符串
  1. assume cs:code
  2. data segment
  3. db 'Welcome to masm!',0
  4. data ends

  5. code segment

  6. start:       
  7.         mov dh,8
  8.         mov dl,3
  9.         mov cl,2
  10.         mov ax,data
  11.         mov ds,ax
  12.         call show_str
  13.         mov si,0
  14.         mov ax,4c00H
  15.         int 21h

  16. show_str:;借用实验9的代码
  17.         mov al,dh
  18.         mov bl,160
  19.         mul bl
  20.         add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
  21.         add al,dl
  22.         mov di,ax
  23.         mov bx,0
  24.         mov ax,0B800H;显存位置
  25.         mov es,ax
  26.        
  27.         mov ah,cl
  28.         mov cx,16
  29. s:        mov al,[bx]
  30.         mov es:[di],al
  31.         inc bx
  32.         inc di
  33.         mov es:[di],ah
  34.        
  35.         inc di
  36.         loop s
  37.         ret
  38.        
  39. code ends
  40. end start
复制代码

这里显存的数据结构卡了我一下,导致我一开始老是输出微笑和奇怪的颜色,后来及时想起
果然ctrl+c大法在发功之前还是得仔细研究一下原理,复制不规范,代码两行泪
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-11 17:16:35 | 显示全部楼层
2.解决除法溢出的问题
  1. assume cs:code


  2. code segment

  3. start:       
  4.         mov ax,4240H;(ax)=L
  5.         mov dx,000FH;(dx)=H
  6.         mov cx,0AH;(cx)=N
  7.         call divdw
  8.        
  9.         mov ax,4c00H
  10.         int 21H
  11.        
  12. divdw:
  13.         push ax;暂时存放一下
  14.         mov ax,dx
  15.         div cl;此时(al)=int(H/N),ah=rem(H/N)
  16.        
  17.         mov bl,al
  18.         mov bh,0;构造int(H/N)*65536
  19.        
  20.         mov di,bx;存放一下
  21.         mov bl,ah
  22.         pop ax;需要的时候再拿出来
  23.         mov bh,0;构造rem(H/N)*65536
  24.         mov dx,bx;构造rem(H/N)*65536+L
  25.         div cx;构造[rem(H/N)*65536+L]/N=(ax)
  26.         mov cx,dx;使(cx)=余数
  27.         add dx,di;构造int(H/N)*65536+[rem(H/N)*65536+L]/N
  28.         ret
  29.        
  30. code ends
  31. end start
复制代码

寄存器不够用是真的麻烦,也许这题还用不着堆栈,可以后更多参数和中间变量了怎么办
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-11 18:55:26 | 显示全部楼层
3.数值显示
  1. assume cs:code
  2. data segment
  3. db 10 dup (0)
  4. data ends

  5. code segment

  6. start:       
  7.         mov ax,12666
  8.         mov bx,data
  9.         mov ds,bx
  10.         call dtoc
  11.         mov dh,8
  12.         mov dl,3
  13.         mov cl,2

  14.         call show_str
  15.        
  16.         mov ax,4c00H
  17.         int 21h

  18. dtoc:
  19.         mov di,0
  20.         mov bx,10
  21.         mov cx,5
  22.         s0:
  23.                 div bx;
  24.                 add dl,30H
  25.                 mov [di],dl
  26.                 mov dx,0
  27.                 inc di
  28.         loop s0
  29.         ret

  30. show_str:;借用实验9的代码
  31.         mov al,dh
  32.         mov bl,160
  33.         mul bl
  34.         add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
  35.         add al,dl
  36.         mov di,ax
  37.         mov bx,5
  38.         mov ax,0B800H;显存位置
  39.         mov es,ax
  40.        
  41.         mov ah,cl
  42.         mov cx,5
  43. s:        dec bx
  44.         mov al,[bx]
  45.         mov es:[di],al
  46.        
  47.         inc di
  48.         mov es:[di],ah
  49.        
  50.         inc di
  51.         loop s
  52.         ret

  53.        
  54. code ends
  55. end start
复制代码

这里令我百思不得其解的是为何debug运行得很成功,但直接运行exe会卡住,希望有大大解答
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-11 21:46:07 | 显示全部楼层
流风逸雪 发表于 2020-4-11 18:55
3.数值显示

这里令我百思不得其解的是为何debug运行得很成功,但直接运行exe会卡住,希望有大大解答

首先,如果有问题,请写在问题贴中
你写在作业贴中很少有人看到你的问题,我看到这个问题纯属巧合

然后是你的问题
div bx
这条指令的含义是
dx:ax / bx
是32位 / 16位

请问执行这条指令之前dx的值是多少?
这就是C语言中的 “使用了未初始化的变量”
出现什么结果都是可能的,程序有时候正常,有时候异常,因为 “使用了未初始化的变量”
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-4-12 14:45:57 | 显示全部楼层
人造人 发表于 2020-4-11 21:46
首先,如果有问题,请写在问题贴中
你写在作业贴中很少有人看到你的问题,我看到这个问题纯属巧合


首先谢谢这位大大的回答。
我没写在问题贴的一个原因是我还没看完小甲鱼的关于这一段的课程,先暂时做个记录,看看能不能独立完成。放在作业贴是觉得会来看的应该是同样在做这一道题的童鞋,这样能得到同一层次的思考和反馈,不至于产生依赖。
我是看完小甲鱼视频再回来修改后才看到大大的回答的,我很认同大大的回答。
这里贴一下修改后的代码,修改后能直接运行exe了:
  1. assume cs:code
  2. data segment
  3. db 10 dup (0)
  4. data ends

  5. code segment

  6. start:       
  7.         mov ax,12666
  8.         mov bx,data
  9.         mov ds,bx
  10.         mov si,0
  11.         call dtoc
  12.         mov dh,8
  13.         mov dl,3
  14.         mov cl,2

  15.         call show_str
  16.        
  17.         mov ax,4c00H
  18.         int 21h

  19. dtoc:
  20.         push dx
  21.         push cx
  22.         push ax
  23.         push si
  24.         push bx
  25.        
  26.         mov bx,0;bx子程序中存放位数,用栈临时存放修改后的字符
  27.         s0:
  28.                 mov cx,10d;d表示十进制
  29.                 mov dx,0;这里小甲鱼的视频里确实做了dx的初始化,说明正如@人造人 所说,问题出在这
  30.                
  31.                 div cx;
  32.                 mov cx,ax;所得商给cx
  33.                
  34.                 jcxz s2;当商为0跳到s2
  35.                 add dx,30H;余数加上30h得到相应的ASCII码
  36.                 push dx
  37.                
  38.                
  39.                 inc bx;存储位数
  40.         jmp short s0
  41. s2:
  42.         add dx,30H
  43.         push dx
  44.         inc bx;再进行一次栈操作(补充当“商为零而余数不为零“的情况)
  45.        
  46.         mov cx,bx;总共有bx位进栈了,所以循环次数为bx
  47.         mov si,0
  48.        
  49. s3:       
  50.         pop ax
  51.         mov [si],al
  52.         inc si
  53.        
  54.         loop s3
  55.        
  56. okay:
  57.         pop bx
  58.         pop si
  59.         pop ax
  60.         pop cx
  61.         pop dx
  62.         ret

  63. show_str:;借用实验9的代码
  64.         push bx
  65.         push cx
  66.         push si
  67.        
  68.         mov al,160
  69.         dec dh
  70.         mul dh
  71.         add dl,dl;显存的奇数字节为字的内容,偶数为字的外观属性,所以要列地址*2作为显存地址
  72.         add al,dl
  73.         mov bx,ax
  74.         mov ax,0B800H;显存位置
  75.         mov es,ax
  76.         mov di,0
  77.        
  78.         mov al,cl
  79.         mov ch,0
  80. s:        mov cl,[si]
  81.         jcxz ok
  82.         mov es:[bx+di],cl
  83.        
  84.         mov es:[bx+di+1],al
  85.         inc si
  86.         add di,2
  87.         jmp short s
  88. ok:       
  89.         pop si
  90.         pop cx
  91.         pop bx
  92.         ret


  93.        
  94. code ends
  95. end start
复制代码

最后我想了一下,确实不应该在作业贴里问问题,毕竟鱼c作为一个开放的平台,应该把内容分类好方便更多的鱼油。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-12 14:57:56 | 显示全部楼层
对于第三题,为了让大家看的更清楚
更直观的明白毛病在哪,就把只修改第30行的代码放这以做对比:

这是原来的dtoc子程序:
  1. dtoc:
  2.         mov di,0
  3.         mov bx,10
  4.         mov cx,5
  5.         s0:
  6.                 div bx;
  7.                 add dl,30H
  8.                 mov [di],dl
  9.                 mov dx,0
  10.                 inc di
  11.         loop s0
  12.         ret
复制代码

这样无法直接运行exe

这是修改后的:
  1. dtoc:
  2.         mov di,0
  3.         mov bx,10
  4.         mov cx,5
  5.         s0:
  6.                 mov dx,0;其实就是单纯的把原来放在30行的mov dx,0放在这就行了
  7.                 div bx;
  8.                 add dl,30H
  9.                 mov [di],dl
  10.                                 ;mov dx,0
  11.                 inc di
  12.         loop s0
  13.         ret
复制代码

这样可以直接运行exe了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-12 15:03:04 | 显示全部楼层
流风逸雪 发表于 2020-4-12 14:45
首先谢谢这位大大的回答。
我没写在问题贴的一个原因是我还没看完小甲鱼的关于这一段的课程,先暂时做 ...

嗯,我同意你的观点,遇到问题应该先自己尝试解决,实在解决不了才提问,这样自己能得到更多知识
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-9 04:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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