马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 兰陵月 于 2017-11-14 00:44 编辑
IA-32架构的基本执行环境—几个知识点的验证学习
By 鱼C论坛 ID:兰陵月 2017.11.13
学习书本来自:
《X86汇编语言-从实模式到保护模式》,P169-P170。
第10章32位X86处理器编程架构
10.1 IA-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,[sp]”是不允许的。编译时,出现了“invalid effective address”错误。
如上图,“move ax,[esp]”是允许的,程序编译通过。
(四)验证指令前缀“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”前缀的反转作用。
|