实验6:传送指令
知识点:
传送指令用于寄存器、存储单元或I/O端口之间传送信息,分为数据传送、地址传送、标志传送和I/O信息传送等。除部分标志传送指令外,其他传送指令不影响标志位的状态。
若将一个n位空间中的数据传送到另一个n位空间中,则传送前后的位串不会改变;若将一个n位空间中的数据传送到另一个m位空间中,则必须满足m≥n,即传送后的位串长度必须大于等于传送前的位串长度,相应分为零扩展和符号扩展两种情况。如图1所示。
实验目的:
1.掌握数据传送类指令,区分符号扩展和零扩展;
2.区分mov指令和lea指令。
实验报告要求:
1.说明你做实验的过程(重要步骤用屏幕截图表示)。
2. 分析或回答问题。
完成下列实验,提交实验报告:
实验1:
(1) -0x16(%ebp)、-0x14(%ebp)、-0x12(%ebp) 、-0x10(%ebp)和-0xc(%ebp)分别是变量x、y、z、p和q的栈地址。如何根据自己的计算机得到x、y、z、p和q的栈地址?修改该程序中汇编指令部分,使得程序能在自己的计算机上正确执行。
(2)6条汇编语句执行结束时,栈帧中x、y、z、p和q的内容分别是什么,画出此时栈帧内容。
(3)6条汇编语句对应的c语句是什么?
//ex6_1
#include "stdio.h"
void main( )
{ short x=0x8543,y=1,z=2;
int p=0x12345678,q=3;
asm (
"movzwl -0x16(%ebp),%eax\n\t"
"mov %ax,-0x14(%ebp)\n\t"
"movswl -0x16(%ebp),%eax\n\t"
"mov %eax,-0xc(%ebp)\n\t"
"mov -0x10(%ebp),%eax\n\t"
"mov %ax,-0x12(%ebp)\n\t"
);
printf("x=%d,y=%d,z=%d\n",x,y,z);
printf("p=%d,q=%d\n",p,q);
}
注意:
(1)x、y和z等变量赋值与否,影响它们在栈中分配空间的位置(地址)。变量没有赋初值的该程序执行结果与赋初值的执行结果可能不一样。为方便读汇编指令,建议所有变量赋初值。
(2)printf语句影响栈帧空间大小。
因此该程序的汇编指令中地址只限定在当前程序中有效。
(3)不同机器gcc编译后可能栈空间地址分配不一样,汇编代码中的地址根据需要修改。
指令的地址是该程序地址空间中的地址,是虚拟地址,非物理内存的地址。这里的memory是程序的虚拟地址空间。
一个数据不管是单独存放在存储器中,还是随着指令存放在存储器中,都有存储时的字节顺序问题
实验2:区分mov指令和lea指令
(1) 下述程序执行过程中,填出esp和ebp的内容和p[0]和p[1]在栈帧中的内容。
(2)5条汇编指令执行后,eax、ebx、ecx和edx的内容各是什么
//ex6_test
#include "stdio.h"
void main( )
{ short x=0x8543,y=1,z=2;
int p=0x12345678,q=3;
y=x;
q=x;
z=p;
printf("x=%d,y=%d,z=%d\n",x,y,z);
printf("p=%d,q=%d\n",p,q);
}
//ex6_2
#include "stdio.h"
void main( ){
int p[2]={0x12345678,0x11223344};
asm (
"mov -0x14(%ebp),%eax\n\t"
"lea -0x14(%ebp),%ebx\n\t"
"mov $1,%ecx\n\t"
"mov -0x14(%ebp,%ecx,4),%edx\n\t"
"lea -0x14(%ebp,%ecx,4),%ecx\n\t"
);
}