汇编网首页登录博客注册
hky987654321的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新留言
好友圈
文章收藏
友情链接

[2013-09-02 17:17] 实验14

任务:以“年/月/日 时:分:秒”的格式,显示当前的日期、时间
    程序1为作业原版,程序2~8为追求最简过程中的改进系列。收集在一起后,整个系列脉络清晰,代码从22条简至13条,但增大的数据段,却有点另类和怪怪的感觉。
    问题:1、再减代码的思路?  2、简至只剩数据段会如何?回归机器语言?
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序1  代码22条(54字节)
data segment 
  db '2090/80/70 40:20:00','$'  ;在相应位置设置所需信息 
data ends 
code segment 
start:  
mov ax,data 
mov ds,ax 
sub dx,dx                  ;设置ds:dx指向data:0 
sub bx,bx          
mov cx,4 
St_s:  
mov al,[bx].2             ;从data取出数据 
mov byte ptr [bx].2,'0'   ;将该位置数据置'0',即30h 
sub al,30h                ;从读取的ASCⅡ码中剥离出单元地址 
mov dl,al                 ;暂存备用    
out 70h,al                ;将该单元地址传到地址端口70h 
in  al,71h                ;从数据端口71h取出单元的数据 
mov ah,al                 ;得到两份数据 
shr al,cl                 ;右移分离得高4位的十位数 
and ah,00001111b          ;与运算得低4位的个位数 
add [bx].2,ax             ;传到data中相加,得ASCⅡ码 
add bx,3                  ;寻址偏移量增加3个单元 
cmp dx,0                  ;读0 
jne St_s                  ;判断结束标识符 
mov ah,9                  ;设置9号子程序 
int 21h                   ;用int 21h输出字符串   
mov ax,4c00h 
int 21h 
code ends 
end start
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序2  代码19条(47字节)
data segment 
db '2000/00/00 00:00:00','$';将单元地址从存放时间处分出
db 9,5,5,8,5,5,7,5,5,4,5,5,2,5,5,0,5,5,'!' ;置结束标识'!',用5区隔统一寻址 
data ends 
code segment 

start: mov ax,data       ; 1 读取数据段地址
mov ds,ax                ; 2 设置数据段
sub dx,dx                ; 3 设置ds:dx指向data:0 
sub bx,bx                ; 4 清0
mov cx,4                 ; 5 设置移位值
St_s: mov al,[bx].20     ; 6 取出数据 
out 70h,al               ; 7 传送单元地址
in  al,71h               ; 8 取出时钟BCD码 
mov ah,al                ; 9 复制,为数据分离作准备 
shr al,cl                ;10 右移4位,分离出高4位的十位数
and ah,00001111b         ;11 and运算纯化出低4位的个位数 
add [bx].2,ax            ;12 将十位数和个位数一并传到data中相加,得ASCⅡ码
add bx,3                 ;13 寻址增3个字节  
cmp byte ptr [bx].20,'!' ;14 是否读到结束标识
jne St_s                 ;15 未读到,继续 
mov ah,9                 ;16 置9号子程序 
int 21h                  ;17 显示字符串        
mov ax,4c00h             ;18 返回
int 21h                  ;19 返回
code ends 
end start 
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code         ;程序3 代码18条(48字节)
data segment   
  db '2000/00/00 00:00:00','$',16  ;新置16,作为8位除数  
  db  9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0,'!';区隔数置为0,使(ah)=0
data ends   
code segment

start: mov ax,data              ; 1 读取数据段地址
mov ds,ax                       ; 2 设置数据段
sub dx,dx                       ; 3 ds:dx指向data:0   
sub bx,bx                       ; 4 清0
St_s: mov ax,[bx].21            ; 5 取出数据,存于ax 
out 70h,al                      ; 6 传送单元地址
in  al,71h                      ; 7 取出时钟BCD码  
or  [bx].3,al                   ; 8 or运算使30h及存入数据的个位均得保存
and byte ptr [bx].3,00111111b   ; 9 使数据纯化为(30h + 个位)  
div byte ptr ds:[20]            ;10 除以16,效同al右移4位得十位数
add [bx].2,al                   ;11 传到data中相加,得其ASCⅡ码
add bx,3                        ;12 寻址增3个字节   
cmp byte ptr [bx].21,'!'        ;13 是否读到结束标识 
jne St_s                        ;14 未读到,继续  
mov ah,9                        ;15 置9号子程序 
int 21h                         ;16 显示字符串 
mov ax,4c00h                    ;17 返回
int 21h                         ;18 返回
code ends   
end start  
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序4 代码17条(46字节)
data segment   
  db '2000/00/00 00:00:00','$',16,0  ;置16和0,作为16位乘数的低8位与高8位
  db  9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0,'!'  ;置0使相乘后(dx)=0成立  
data ends   
code segment 
  
start: mov ax,data            ; 1 读取数据段地址
mov ds,ax                     ; 2 设置数据段
sub bx,bx                     ; 3 清0
St_s: mov ax,[bx].22          ; 4 取出数据
out 70h,al                    ; 5 传送单元地址
in  al,71h                    ; 6 取出时钟BCD码
or  [bx].3,al                 ; 7 or运算使30h及存入数据的个位均得保存   
and byte ptr [bx].3,00111111b ; 8 and运算清除残余使数据纯化为(30h + 个位) 
mul word ptr ds:[20]          ; 9 乘以16,ax左移4位,ah存十位数,并置(dx)=0
add [bx].2,ah                 ;10 传到data中相加,得其ASCⅡ码
add bx,3                      ;11 寻址增3个字节    
cmp byte ptr [bx].22,'!'      ;12 是否读到结束标识
jne St_s                      ;13 未读到,继续 
mov ah,9                      ;14 置9号子程序  
int 21h                       ;15 输出字符串
mov ax,4c00h                  ;16 返回
int 21h                       ;17 返回
code ends   
end start
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序5  代码16条(42字节)
data   segment
   db '2000/00/00 00:00:00','$',16,0       ;置16和0,16位乘数的低8位与高8位
   db  9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0 ;置0使相乘后(dx) = 0 成立
   db  0,9,0,0,4ch                         ;置(ah) = 9 、4ch 及(al) = 0
data   ends
code   segment

 start:mov ax,data             ; 1 读取数据段地址
       mov ds,ax               ; 2 设置数据段
       sub bx,bx               ; 3 本条亦可删除,但一般不主张
 St_s: mov ax,[bx].22          ; 4 从data中取出数据,存于ax
       cmp ah,9                ; 5 是否读到ah=9或4ch
       jnb Ok                  ; 6 读到,显示时钟或返回
       out 70h,al              ; 7 传送单元地址
       in  al,71h              ; 8 取出时钟BCD码
       or  [bx].3,al           ; 9 分存到数据段中
       and byte ptr [bx].3,3fh ;10 分存数据纯化为(30h + 个位)
       mul word ptr ds:[20]    ;11 乘以16,ax左移4位,ah存十位数,并置(dx)=0
       add [bx].2,ah           ;12 传到data中相加,得其ASCⅡ码
Return:add bx,3                ;13 寻址增3个字节
       jmp St_s                ;14 继续
   Ok: int 21h                 ;15 输出时钟或返回
       jmp Return              ;16 转去使(ax)=4c00h
code   ends
end    start
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序6  代码14条(40字节)
code   segment
   db '2000/00/00 00:00:00','$',16,0       ;置16和0,16位乘数的低8位与高8位 
   db  9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0 ;置0使相乘后(dx) = 0 成立 
   db  0,9,0,0,4ch                         ;置(ah) = 9 、4ch 及(al) = 0 
   dw  0 , seg start                       ;32位地址cs:0 (seg为后章知识)
   
 start:LDS bx,cs:[45]          ; 1 ds:bx = cs:0 (LDS在杨季文的书中可学)
 St_s: mov ax,[bx].22          ; 2 取出数据,存于ax 
       cmp ah,9                ; 3 是否读到ah=9或4ch 
       jnb ok                  ; 4 读到,显示时钟或返回 
       out 70h,al              ; 5 传送单元地址 
       in  al,71h              ; 6 取出时钟BCD码      
       or  [bx].3,al           ; 7 分存到数据段中 
       and byte ptr [bx].3,3fh ; 8 分存数据纯化为(30h + 个位) 
       mul word ptr ds:[20]    ; 9 乘以16,ax左移4位,ah存十位数,并置(dx)=0 
       add [bx].2,ah           ;10 传去相加,得其ASCⅡ码
return:add bx,3                ;11 寻址增3个字节 
       jmp St_s                ;12 继续 
   ok: int 21h                 ;13 输出时钟或返回 
       jmp return              ;14 转去使ax=4c00h 
code   ends 
end    start
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序7  代码13条(35字节)
code   segment
   db '2000/00/00 00:00:00','$',10h        ;置10h(即16),8位除数
   db  9,0,0,8,0,0,7,0,0,4,0,0,2,0,0,0,0,0 ;置0,使(ah)=0且统一读写寻址
   db  0,9,0,0,4ch                         ;置(ah) = 9 、4ch 及(al) = 0
   dw  0 , seg start                       ;存放32位地址 cs:0 seg为后章知识

 start:LDS bx,cs:[44]          ; 1 ds:bx = cs:0 LDS在杨季文的书中可学
       XOR dx,dx               ; 2 置0 XOR在杨季文的书中可学
  St_s:mov ax,[bx].21          ; 3 取出数据,存于ax
       cmp ah,9                ; 4 是否读到ah=9或4ch
       jnb ok                  ; 5 读到,显示时钟或返回
       out 70h,al              ; 6 传送单元地址
       in  al,71h              ; 7 取出时钟BCD码
       div byte ptr ds:[20]    ; 8 除以10h,商(al)、余数(ah)为十位数、个位数
       add [bx].2,ax           ; 9 传去相加,得其ASCⅡ码
return:add bx,3                ;10 寻址增3个字节
       jmp St_s                ;11 继续
   ok: int 21h                 ;12 显示时钟或返回
       jmp return              ;13 转去使ax=4c00h
code   ends
end    start
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - 
assume cs:code        ;程序8  代码19条(64字节)
code   segment
   db  9,'/',8,'/',7,' ',4,':',2,':',0,4ch,10h  ;单元地址、返回及除数
   dw  0 , 0b800h             ;存放32位地址 es:0

 start:LES bx,cs:[13]         ; 1 es:bx=b800h:0
       xor di,di              ; 2 清0
  St_s:mov ax,cs:[bx]         ; 3 取出数据,存于ax
       mov dx,ax              ; 4 暂存
       out 70h,al             ; 5 传送单元地址
       in  al,71h             ; 6 取出时钟BCD码
       xor ah,ah              ; 7 清0
       div byte ptr cs:[12]   ; 8 除以10h,商(al)、余数(ah)为十位数、个位数
       add ax,3030h           ; 9 转化为ASCII码
       mov es:3840[di],al     ;10 显示时钟十位数
       mov es:3842[di],ah     ;11 显示时钟个位数
       mov ax,dx              ;12 还原
       cmp ax,4c00h           ;13 是否读到返回值
       je over                ;14 是转结束
       mov es:3844[di],ah     ;15 显示时钟数字分隔符
       add bx,2               ;16 读数据寻址增2
       add di,6               ;17 显示寻址增6
       jmp St_s               ;18 继续
  over:int 21h                ;19 返回
code   ends
end    start
评论次数(1)  |  浏览次数(858)  |  类型(汇编作业) |  收藏此文  | 

[  游客   发表于  2014-03-02 15:46  ]

没想到实验14只用13条代码!

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码