第4天:C语言与画面显示的练习
英特尔电脑CPU家谱
8086->80186->286->386->486->Pentium->PentiumPro->Pentium Ⅱ->…
286及以前CPU是16位的,386及以后CPU是32位的。
一段汇编程序
_write_mem8: ; void write_mem8(int addr, int data);
MOV ECX,[ESP+4] ; [ESP+4]中存放的是地址,将其读入ECX
MOV AL,[ESP+8] ; [ESP+8]中存放的是数据,将其读入AL
MOV [ECX],AL
RET
SP是16位CPU的栈顶指针,栈从低处向高处生长;ESP是32位CPU的栈顶指针。由于一个数据是32位,内存按字节编址,1字节8位,32位相当于4字节,则下一个数据需要从4地址之后读取。
指针的汇编理解
第二天中的BYTE对应1字节,WORD对应2字节,DWORD对应4字节。上面的_write_mem8,其实只相当于一条C语言语句,*i= data.但是这样会报类型错误。如果学汇编之前,我们知道这样会类型错误,知道怎样改,但是不知道底层是怎样工作的。现在我们知道这时编译器在做什么了。在执行这条命令时,假设*i指向地址为0x1234,data为0x56,编译器会运行MOV [0x1234],0x56.这没有指明0x56的赋值目标空间大小——到底是BYTE,还是WORD,还是DWORD?所以不对。
所以,如果改正,要先声明指针指向的空间大小。在C语言中,就需要先定义指针的数据类型。**char大小BYTE,short大小WORD,int大小DWORD。**则此处要先定义char *i即可。**但是注意,无论是char *i,还是short i,亦或是int i,这些地方i都是4字节变量,这是因为i是用于记录地址的变量,在汇编语言中,地址也像ECX一样,用4字节的寄存器来指定。
书中指出了一个很有趣的事情,a为数组,i为int变量,则a[i]和i[a]是等价的,都可以表示数组a从0开始的第i号元素,并不报错。
C语言语句的汇编基础
char a[3];
相当于汇编语言
a:
RESB 3
a是标志符,3是常数,作为汇编语言中的保留变量。
今日总结
四天,看作者实现了一个操作系统的图形界面的初步框架。代码没有自己写,运行的作者的代码包,关键部分努力理解了。