任务:以“年/月/日 时:分:秒”的格式,显示当前的日期、时间
程序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
- [游客] 为啥简版的int 13h之后不用 jmp 也行。 08/31 00:14
- [hky987654321] 是的,按压F1的次数 >=15 ,有“按下“→”键会出现光斑落在年份的百位数上”的现象。 这与缓冲 08/09 11:12
- [游客] 为什么多次按F1后,按下“→”键会出现光斑落在年份的百位数上? 08/02 21:42
- [游客] 懂了。 07/30 10:54
- [hky987654321] -1就是FFh。用-1兼济了ffff:0和简洁的数据分隔这二者的需要。 [bp-2],是因为刚进入 07/29 11:43
- [游客] 也看不懂[bp-2] 07/12 10:49
- [游客] 不懂-1 07/09 17:55
- [游客] 16位现在只有教学意义,看一眼就好。 04/13 00:46
- [游客] 没搞错吧,课程2才351b 03/09 18:01
- [游客] 没想到实验14只用13条代码! 03/02 15:46
[ 游客 发表于 2014-03-02 15:46 ]
没想到实验14只用13条代码!