先谢谢wmf2014班竹也来玩儿
继续我们的缩小旅程…
回圈比标准写法复杂,似乎没有再缩小的空间,此路已走到尽头。
程式的迷宫中得找另一条捷径,我们想到资料表。
先建立一个三个资料的表格,每一项资料表示:字节,长度
就这样 buff db '0',10,'a',26,'A',26
改写程式
程序代码:
CODE segment
assume cs:CODE,ds:CODE,es:CODE,ss:CODE
org 100h
start:
mov si,offset buff
mov cx,3
S10:
push cx
lodsw ;读入DS:SI一个word入AX,并且SI自动加1,al=字节,ah=回圈长度
mov cl,ah ;取回圈长度,这里ch已经=0
S20:
mov ah,0eh
int 10h
inc al
loop S20 ;内回圈
pop cx ;外回圈三次
loop S10
int 20h
buff db '0',10,'a',26,'A',26
CODE ENDS
END START
共29bytes,可以进一步缩小差距吗?
可以的,这里要借助dos的特性
特性一:
返回dos方式标准
mov ah,4ch
int 21h
早期的方式(不推荐)
int 20h
另有更简单的方法:RET
程式被载内存,dos会为它保留100H作系统和程式沟通之用,
这叫PSP,PSP:0的偏移首2个BYTE是CD 20,CD 20便是INT 20H
只要CS指向PSP段,JMP 0就会跳到这道指令
而COM被载入时CS,DS,SS,ES都指向PSP段,SP指向FFFEH,栈顶处通常会是0
一通RET就弹出0值送入IP,然后跳去PSP:0,执行INT 20H
特性二:
列印字符方法有好几种,常用的
mov dl,字符
mov ah,2
int 21h
;----6 bytes
mov al,字符
mov ah,0eh
int 10h
;----也是6 bytes,但直接用al,不须经dl,在回路中应该可以减省空间
其实dos另有一道后门,int 29h...快速输出字符
mov al,字符
int 29h
ok,把上面的程式换用这两个特性
程序代码:
CODE segment
assume cs:CODE,ds:CODE,es:CODE,ss:CODE
org 100h
start:
mov si,offset buff
mov cx,3
S10:
push cx
lodsw ;读入DS:SI一个word入AX,并且SI自动加1,al=字节,ah=回圈长度
mov cl,ah ;取回圈长度,这里ch已经=0
S20:
int 29h
inc al
loop S20 ;内回圈
pop cx ;外回圈三次
loop S10
ret
buff db '0',10,'a',26,'A',26
CODE ENDS
END START
26 bytes,很接近了!
顺便说说,有了dos这两个特性,题目一的7个bytes就不是什么难事了
[此贴子已经被作者于2016-6-10 14:59编辑过]