兰陵月 发表于 2017-11-13 21:55:38

【原创】IA-32架构的基本执行环境—几个知识点的验证学习

本帖最后由 兰陵月 于 2017-11-14 00:44 编辑

IA-32架构的基本执行环境—几个知识点的验证学习

By 鱼C论坛ID:兰陵月    2017.11.13

学习书本来自:
《X86汇编语言-从实模式到保护模式》,P169-P170。
第10章32位X86处理器编程架构
10.1IA-32架构的基本执行环境

编译器如下图:

调试器:

操作验证方法:构建一个实模式下运行的主引导程序,编写相关指令,运行后在调试器中测试验证。
    一、实模式下32位寄存器的使用


(一)源操作数和目的操作数长度不一致验证
    书中P170页内容:

编程序验证如下:

上图中,上面红框中“mov eax,cx”和“mov eax,ch”为非法语句,在编译的时候出现“error:invalid combination of opcode and operands”错误,编译不能通过。

如上图,将错误语句注释后,再次进行编译,显示编译完成。

(二)实模式下32位寄存器的使用

mov eax,0xf0000005

mov eax,0xf5

mov ecx,eax

add edx,ecx

jmp near $

times 510-($-$) db 0

db 0x55,0xaa

将编译后的bin文件在Bochs中执行,并将前4条语句反编译成汇编语言,如下图红框内内容:

本程序运行在实模式下,可以看到源程序第4行中的立即数“0xf5”在编译后变成了32位的“0x000000f5”。验证了下图内容:


下面是执行前3条语句的调试情况。
执行“mov eax,0xf0000005”后,查看寄存器EAX内容:

执行“mov eax,0xf5”后,寄存器EAX内容内容:

执行“mov ecx,eax”后,寄存器内容:

执行“add edx,ecx”后,寄存器内容:

上述三条指令均在16位模式下(实模式)运行,均可以正常使用。

(三)验证16位和32位模式下的栈指针寄存器使用



如上图,“mov ax,”是不允许的。编译时,出现了“invalid effective address”错误。

如上图,“move ax,”是允许的,程序编译通过。

(四)验证指令前缀“0x66”。
源程序如下图:


在Bochs中运行后,反编译前面4条语句,如下图:

mov ecx,eax 机器码:66 89 c1
mov cx,ax   机器码:89 c1
add edx,ecx机器码:66 01 ca
add dx,cx    机器码:01 ca
本程序运行在16位实模式下,因此原本就是16位的语句如“mov cx,ax”和“add dx,cx”的前面没有前缀“66”。而本为32位的语句如“mov ecx,eax”和“add edx,ecx”前面则加了前缀“66”。

同时,通过软件查看编译后的二进制文件,可以看到,如下图:

上图中红线部分,分别是前面4条语句。也可以在相应位置看到前缀“66”。

反过来,我们可以想到,假如去掉了“66”这个字节,在16位模式的编译下,前面两条语句将变得一样,后面两条语句也将变得一样。
同样也证明了,同样的机器指令,在16位和32位模式下解释是不同的。
即证明了下面的内容:


(五)验证指令前缀“0x66”的反转作用
源程序图如下:

在Bochs中运行编译好的文件,再在Bochs中反编译这几条语句,如下图:

仔细观察源程序中的4条语句和Bochs中反编译后的4条语句,发现:
1、在bits 16部分,反编译的结果和源程序的内容一致。这是因为本程序本来就运行在16位的实模式下,所以编译结果与源程序一致。
2、在bits 32部分,反编译的结果和源程序的内容不一致,发生了变化。
源程序为:
mov cx,dx
mov eax,ebx
在Bochs中反编译后为:
mov ecx,edx
mov ax,bx

证明了“0x66”前缀的反转作用。

邪恶的伞 发表于 2017-11-13 22:00:52

{:10_257:}

兰陵月 发表于 2017-11-13 22:02:47

邪恶的伞 发表于 2017-11-13 22:00


{:10_247:}
还在编写中。。。。。。。。。。
页: [1]
查看完整版本: 【原创】IA-32架构的基本执行环境—几个知识点的验证学习