鱼C论坛

 找回密码
 立即注册
查看: 3889|回复: 5

[汇编作业] 汇编语言-实验十-屏幕显示12666

[复制链接]
发表于 2016-8-3 08:48:59 | 显示全部楼层 |阅读模式

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

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

x
分享一下代码和学习心得
1、用到loop s时,自然会修改cx的值,要小心使用cx时用loop指令,jmp是个不错的选择,或将cx入栈

2、栈的使用,子程序中将寄存器的值入栈,运行完子程序后将寄存器的值出栈,不会影响指针  sp  的值,只需要做到栈足够大,在子程序的运行过程中栈不越界,否则会影响到调入内存中的其他值,如:可能改变你的指令,从而影响程序的正确执行。

代码分享:
(这个代码实现的是:显示出来的是66621,倒序,做之前没有看答案)
  1. assume cs:code

  2. data segment
  3. db 10 dup(0)                        ;16B,准备放置屏幕要显示的内容
  4. data ends

  5. stack segment
  6. dw 16 dup(0)                        ;32B
  7. stack ends

  8. code segment
  9. start:
  10.         mov ax,stack
  11.         mov ss,ax
  12.         mov sp,32

  13.         mov ax,12666                ;初始给定的word型数据<65536,最大5位数

  14.         mov bx,data
  15.         mov ds,bx                ;初始给定的十进制值及颜色值的存放位置
  16.         mov si,0

  17.         call dtoc

  18.         mov dh,8                ;给定显示的位置及颜色要求:8行3列、绿色
  19.         mov dl,3
  20.         mov cl,2
  21.         call show_str
  22.         mov ax,4c00h
  23.         int 21h

  24. dtoc:
  25.         ;此子程序要求给定16位被除数在寄存器ax中,除数为8位=10
  26.         ;转换结果存在ds:[si]中
  27.         ;此程序要求栈段的长度为32B

  28.         push ax
  29.         push bx
  30.         push cx
  31.         push dx
  32.         push si
  33.        
  34.         mov dx,10                ;设定除数
  35.         mov bx,ax
  36. dtoc_s:        mov ah,0
  37.         mov al,bh
  38.         div dl
  39.         mov ch,al
  40.         mov al,bl
  41.         div dl
  42.         mov cl,al

  43.         add ah,30h
  44.         mov ds:[si],ah                ;余数写入内存ds:[si]中
  45.         jcxz dtoc_ok
  46.         inc si
  47.         mov bx,cx
  48.         jmp dtoc_s
  49.        
  50.        
  51. dtoc_ok:
  52.         pop si
  53.         pop dx
  54.         pop cx
  55.         pop bx
  56.         pop ax
  57.         ret

  58. show_str:
  59.         ;此子程序要求给定值在相应的寄存器中:行=dh,列=dl,颜色值=cl
  60.         ;此程序要求栈段的长度为32B

  61.         push ds
  62.         push es
  63.         push si
  64.         push di
  65.         push ax
  66.         push bx
  67.         push cx
  68.         push dx
  69.        
  70.         ;求目标地址
  71.         mov ax,0b800h
  72.         mov es,ax
  73.         mov di,0
  74.        
  75.         mov ax,0
  76.         mov al,160
  77.         dec dh                        ;从0行开始计数
  78.         add dh,2                ;显存从第3行开始显示
  79.         mul dh
  80.         add di,ax

  81.         mov ax,0
  82.         mov al,2
  83.         dec dl
  84.         mul dl
  85.         add di,ax

  86.         mov ah,cl
  87.         mov cx,0                ;清空cx的值

  88.         ;向目标地址写入数据       
  89. show_str_s:       
  90.         mov cl,ds:[si]
  91.         jcxz show_str_ok
  92.         mov al,ds:[si]
  93.         mov es:[di],al
  94.         mov es:[di+1],ah
  95.         inc si
  96.         add di,2
  97.         jmp show_str_s

  98. show_str_ok:       
  99.         pop dx
  100.         pop cx
  101.         pop bx
  102.         pop ax
  103.         pop di
  104.         pop si
  105.         pop es
  106.         pop ds
  107.         ret       

  108. code ends
  109. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-8-3 09:07:59 | 显示全部楼层
one  idea:子程序不会改变sp的值,不用考虑入栈的问题,我在写此程序时还误考虑sp入栈的问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-3 10:47:38 | 显示全部楼层
改进了程序,这次竟然忘记了将每次求得的余数转换为ASCII码,汗!!!显示为乱码
辛苦的每步debug-t才发现。
  1. assume cs:code

  2. data segment
  3. db 10 dup(0)                        ;16B,准备放置屏幕要显示的内容
  4. data ends

  5. stack segment
  6. dw 16 dup(0)                        ;32B
  7. stack ends

  8. code segment
  9. start:
  10.         mov ax,stack
  11.         mov ss,ax
  12.         mov sp,32

  13.         mov ax,data
  14.         mov ds,ax                ;初始给定的十进制值及颜色值的存放位置
  15.         mov si,0
  16.         mov di,0

  17.         mov ax,12666                ;初始给定的word型数据<65536,最大5位数
  18.         call dtoc_4bdiv2b

  19.         mov dh,8                ;给定显示的位置及颜色要求:8行3列、绿色
  20.         mov dl,3
  21.         mov cl,2
  22.         call show_str

  23.         mov ax,4c00h
  24.         int 21h

  25. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  26. show_str:
  27.         ;参数:行=dh,列=dl,颜色值=cl
  28.         ;返回值:将内存中的ASCII码内容显示出来

  29.         ;此子程序要求给定值在相应的寄存器中:行=dh,列=dl,颜色值=cl
  30.         ;此程序要求栈段的长度为32B

  31.         push ds
  32.         push es
  33.         push si
  34.         push di
  35.         push ax
  36.         push bx
  37.         push cx
  38.         push dx
  39.        
  40.         ;求目标地址
  41.         mov ax,0b800h
  42.         mov es,ax
  43.         mov di,0
  44.        
  45.         mov ax,0
  46.         mov al,160
  47.         dec dh                        ;从0行开始计数
  48.         add dh,2                ;显存从第3行开始显示
  49.         mul dh
  50.         add di,ax

  51.         mov ax,0
  52.         mov al,2
  53.         dec dl
  54.         mul dl
  55.         add di,ax

  56.         mov ah,cl
  57.         mov cx,0                ;清空cx的值

  58.         ;向目标地址写入数据       
  59. show_str_s:       
  60.         mov cl,ds:[si]
  61.         jcxz show_str_ok
  62.         mov al,ds:[si]
  63.         mov es:[di],al
  64.         mov es:[di+1],ah
  65.         inc si
  66.         add di,2
  67.         jmp show_str_s

  68. show_str_ok:       
  69.         pop dx
  70.         pop cx
  71.         pop bx
  72.         pop ax
  73.         pop di
  74.         pop si
  75.         pop es
  76.         pop ds
  77.         ret       

  78. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  79. dtoc_4bdiv2b:
  80.         ;参数:数据由ax给出
  81.         ;返回值:转换为10进制数的ASCII码存放在内存ds:0处,正常顺序存放

  82.         ;此子程序要求被除数最大为32位,除数最大为16位,直接按照16位除数进行运算
  83.         ;此程序要求栈段的长度为32B

  84.         push ax
  85.         push bx
  86.         push cx
  87.         push dx
  88.         push si

  89.         mov di,0
  90. dtoc_4bdiv2b_s:
  91.         mov dx,0        ;被除数、除数最大16位,不会溢出,直接div即可
  92.         mov bx,10
  93.         div bx
  94.         add dx,30h        ;余数在dx中,实际只会在dl中,dh为0
  95.         push dx                ;切勿忘记+30h,转换为ASCII码
  96.         inc di                ;计数1次
  97.         mov cx,ax
  98.         jcxz dtoc_4bdiv2b_s2
  99.         jmp short dtoc_4bdiv2b_s
  100. dtoc_4bdiv2b_s2:
  101.         mov cx,di        ;将计数转入cx进行loop循环
  102. dtoc_4bdiv2b_s1:
  103.         pop ax
  104.         mov ds:[si],al
  105.         inc si
  106.         loop dtoc_4bdiv2b_s1

  107. dtoc_4bdiv2b_ok:
  108.         pop si
  109.         pop dx
  110.         pop cx
  111.         pop bx
  112.         pop ax
  113.         ret       
  114.        
  115. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  116. dtoc_2bdiv1b:
  117.         ;参数:ax给出被除数
  118.         ;返回值:转换结果存在ds:[si]中,逆序存放

  119.         ;此子程序要求给定16位被除数在寄存器ax中,除数为8位=10
  120.         ;此程序要求栈段的长度为32B

  121.         push ax
  122.         push bx
  123.         push cx
  124.         push dx
  125.         push si
  126.        
  127.         mov dx,10                ;设定除数
  128.         mov bx,ax
  129. dtoc_2bdiv1b_s:
  130.         mov ah,0
  131.         mov al,bh
  132.         div dl
  133.         mov ch,al
  134.         mov al,bl
  135.         div dl
  136.         mov cl,al

  137.         add ah,30h
  138.         mov ds:[si],ah                ;余数写入内存ds:[si]中
  139.         jcxz dtoc_2bdiv1b_ok
  140.         inc si
  141.         mov bx,cx
  142.         jmp dtoc_2bdiv1b_s
  143.        
  144.        
  145. dtoc_2bdiv1b_ok:
  146.         pop si
  147.         pop dx
  148.         pop cx
  149.         pop bx
  150.         pop ax
  151.         ret

  152. code ends
  153. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-3 10:49:04 | 显示全部楼层
直接套用大规律,即通用性强的处理方法,适应更广阔的条件的方法,可以节省很多繁琐的处理代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-3 10:51:29 | 显示全部楼层
程序的方法很重要,
1、设计好处理时间的逻辑方法、数学解决办法,然后用代码将其逐步实现
2、按此顺序可减少代码的出错,因为很容易漏掉一行应该处理的代码,而使程序处理结果超出想象
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-3 11:58:36 | 显示全部楼层
17066038 发表于 2016-8-3 10:49
直接套用大规律,即通用性强的处理方法,适应更广阔的条件的方法,可以节省很多繁琐的处理代码

1、被除数为16位,除数为8位,直接按照32位/16位,肯定不会溢出,因为商不会超出16位
2、被除数为32位是,8086cpu为16位,就无法进行扩充为64/32的做法了,需要用到divdw的子程序了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-12 17:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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