7 当心寄存器(harib17g)
hello.hrb的大小现在是21个字节,能不能再让它变小点呢?我们做了如下修改,用了一个循环。
本次的hello.nas
[INSTRSET "i486p"]
[BITS 32]
MOV ECX,msg
putloop:
MOV AL,[CS:ECX]
CMP AL,0
JE fin
INT 0x40
ADD ECX,1
JMP putloop
fin:
RETF
msg:
DB "hello",0
改成这样后make一下,hello.hrb变成了26个字节,居然还大了5个字节,哎,好失望。不过,这样改也有好处,即便以后要显示很长的字符串,程序也不会变得太大。
马上运行一下看看。
哎呀?
咦?为啥只显示出一个h呢?再把hello.nas仔细检查一遍,也没发现什么不对劲的地方啊……
■■■■■
既然应用程序没问题,那问题肯定出在操作系统身上。不过,到底是哪里有问题呢?刚刚找到了点眉目,我们给_asm_cons_putchar添上2行代码,就是PUSHAD和POPAD。
本次的naskfunc.nas节选
_asm_cons_putchar:
STI
PUSHAD ; 这里!
PUSH 1
AND EAX,0xff ; 将AH和EAX的高位置0,将EAX置为已存入字符编码的状态
PUSH EAX
PUSH DWORD [0x0fec] ; 读取内存并PUSH该值
CALL _cons_putchar
ADD ESP,12 ; 将栈中的数据丢弃
POPAD ; 这里!
IRETD
为什么要这么改我们待会儿再讲,先来试验一下哦。
哦,好了!
果然是这个问题呀。那为什么会想到加上PUSHAD和POPAD呢?因为笔者推测这有可能是INT 0x40之后ECX寄存器的值发生了变化所导致的,应该是_cons_putchar改动了ECX的值。因此,我们加上了PUSHAD和POPAD确保可以将全部寄存器的值还原,这样程序就能正常运行了。