汇编语言学习笔记(2)

2019-03-10 15:59

哈哈,看到了没,正确的是这个:00403000: 12 34 12 78 56 34 12 74-68,这是为什么? 还有就是这个程序打印的三个结果又是什么呢?是12h和0012h和00000012h吗?如果是,那你就错了哦,应该是:the number is=12h the number is=3412h the number is=78123412h

呵呵,首先,你得明白这三个你定义的数据在内存是怎么存的,一个原则就是你定义的数据的高位存在内存中的高字节地址,你定义的第二个数据:1234h,高位字节是12吧,低位字节是34吧,所以编译器它先存34字节存在内存的低地址,然后再把12存在高地址,当然如果是你只定义了一个字节那顺序就没反了,就像你定义的第一个字节数据12好一样,同样第三个双自数据12345678h,编译器它就先存78好字节了,然后是56好字节,34h字节,12h字节。下面我们来看看程序: mov al,a,就是是把12h放到al中,movzx ax,al 0扩展指令,将al中的字节扩展到ax中,不足的位用0填充,不改变al的值,al里面是什么值,扩展后ax的值还是等于al中的值。 movzx eax,ax ;0扩展指令,将ax中的字节扩展到eax中,不足的位用0填充,不改变ax的值,al里面是什么值,扩展后eax的值还是等于ax中的值。然后push eax,和 push offset msg1,call printf 就是调用c语言库函数printf打印消息, 就相当于c语言里面的:printf(\ number is=%xh\\n\下面的和这段一样,我就不写废话了。如果面对的是有符号数,那就得用movsx了,当然还有其他指令,后面再介绍。

浮点数:

在计算机内部,浮点数是以二进制表示的,所以,要先转换为二进制浮点数,转换分两部,整数部分的装换,采用“除2取余法”,小数部分的装换,采用“乘2取整法”,例如19.2, 先将19 转换成二进制:10011,然后将0.2转换成二进制:00110011……0011,它是个无穷循环小数,然后就是规格化,分三种情况:如果定义的数据类型是dword或者是real4,那么符号位占一位,阶码占8位,位数占23位,总共是32位,如果定义的类型是qword或

real8,那么符号位占一位,阶码占11位,位数占52位,总共64位,如果定义的类型是real10或者是tword,那么阶码占15位,位数占64位,符号位占一位,总共80位。怎么算阶码呢?如果是32位,就将阶码加上127,然后转换成二进制,如果是64位,就加上1023,如果是80位,就加上16383。我们看看怎么将19.2转换成32位的二进制浮点数:

首先将19转换成二进制:10011,然后将0.2转换成二进制:00110011……0011,整理成32位就是:10011,001100110011001100110011001。然后规格化为:1,0011001100110011001100110011001x2的4次方,阶码为127加4等于131:10000011。所以当浮点数19.2表示为三种不同的数据类型为: 32位(dword,real4):0,10000011,0011001100110011001101 64位(qword,real8):0,1000000000110011001100110011001100110011001100110011001100110011 80位:0,100000000000011001100110011001100110011001100110011001100110011001100110011001100110011。 转换成16进制就是4199999Ah,40333333 33333333 h,403999999999999999ah。 然后我们yong程序来验证一下对不对。例子如下: .386

.model flat,stdcall option casemap:none

includelibmsvcrt.lib

printf proto C :VARARG .data

f1 real419.2 f2 real819.2 f3 real10 19.2 msg1 db \.code start: call main ret main proc local f:real8 fld dword ptr f1 fstp f push dword ptr f+4 push dword ptr f+8 push offset msg1

,, call printf add esp,12 push dword ptr f2+4 push dword ptr f2 push dword ptr offset msg1 call printf add esp,12 fld f3 fstp qword ptr f push dword ptr f+4 push dword ptr f+8 push offset msg1 call printf add esp,12 ret mainendp end start

程序很简单,就是分别在屏幕上打印三个浮点值,如下图:

在这里我要说明下,我只有把32位和80位的转换为64位的,才能打印成功,这可能是库函数printf的原因,怎么转换呢?

32位浮点转换64位浮点:首先得借助一个64位的浮点局部变量:

local f:real8 fld dword ptr f1 fstp f

第一句定义了f位一个64位的浮点局部变量,第二句就是把32位浮点数转换为80位的,然后第三句就是把80位的转换位64位的。

80位浮点转换位64位浮点数:同样借助一个64位的浮点局部变量: fld f3 fstp qword ptr f

第二句就是把80位的浮点转换位60位的。

但是这两句怎么解释呢:push dword ptr f2+4 push dword ptr f2 为什么要先把f2的高4位字节入栈呢?

好,我们先来看看这个数转换成64位的16进制为:40333333 33333333h,前面我说了高低对应原则,那么这个64位的16进制在内存中高4字节地址应该存40333333h,也就是存它的高4字节,然后是33333333h,但是,呵呵,在堆栈中的地址是从高往低增长的,所以我们应该先把这个数的高四字节入栈,也就是40333333h,怎么在内存中得到这高4字节呢?就是从f2+4处压入4字节就可以了,然后就是低4字节入栈。如果还没理解,用cdb调试一下就清楚了。

浮点与整数之间的转换: 先看例子成ch2-4: .386

.model flat,stdcall option casemap:none

includelibmsvcrt.lib

printf proto C :VARARG .data

f1 real819.2 f2 dword 20 msg1 db \msg2 db \.code start: call main ret main proc local f:real8


汇编语言学习笔记(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:遥远的爱—黄林芳

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: