汇编语言学习笔记_第1页
汇编语言学习笔记_第2页
汇编语言学习笔记_第3页
汇编语言学习笔记_第4页
汇编语言学习笔记_第5页
已阅读5页,还剩48页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、汇编语言学习笔记-傻瓜学汇编前言当我在学汇编的时候发现一到了实际编程就发现学过的那些指令串不起来,什么浮点数啊整数啊,怎么跳转啊,怎么循环啊,脑袋立马变成浆糊。下面的文档是我的学习经历,希望对初学者在学习加密解密,软件调试,单片机编程有点帮助。目录1. 编程环境的搭建2. 深入理解汇编语言的数据3. 顺序程序设计4. 分支结构程序设计5. 循环6. 数组及指针7. 函数8. 结构9. 综合运用10. 参考文献:编程环境的搭建首先装好masm32v10 和 windbg, 和 editplus, 然后在 editplus 中输入下面的程序,具体的请参考罗云彬的那本书,里面有详尽的说明,编译运行看

2、看:.386.model flat,stdcalloption casemap:noneincludelibmsvcrt.libprintf proto C :VARARG.datamsg db "hello,this is the first test program!", 0dh ,0ah,0 .code start:call mainretmain procpush offset msg call printf add esp,4push offset msgcall printfadd esp,4 ret mainendp end start下面是运行结果:c :&

3、gt;set i ncl licIe»c :ina5fn3 2i ncl udl&C iXProgram Fil esMi crosoft Vi sual Studi oVC38 Incl ude;C :PrcQram Fi 1crooft Vi sual 5tudiciVC98消FC工ncl udcC ;>set 1 i b- c: piasm3 211LC :>set path=c :nia5in3?Li r; c :oracl eXoraSXbi n ;C:Progrm F11 esOracl ejrel 14 ? Kbi n;C: WI ND0W5sy &

4、#163;t&m32;C :WI MDOWS; C :'工 NDOWS£y st em3 2Wb em;C:P rogram File sCo mor Fi 1 esGTK240bi n;C :Program Fi 1 eA.AutodeskDWG TrueVi ew;C ;Program Fi 1 es rli crosoft 或 L 5erver?OTool sbi nri; C :PrograrTi Fil crosoft Visual Studi cCom monXTool sWi nNT;C :Prcigram Fi 1 espii crosoft Vi s

5、ual 5tLidioCorrmonpiSDev98Bi n;C :P |roqdm FilesMicrosoft Visual StudicConrnoriTools;CAPraqram FilsMtcrosoft Vis ual StudioVC9Bbin;D:StcrmIlVjodec;D:StomiIIC iicd Ciwbchl t :behl> rmake rlicrosoft,R) Prograjn Maintenance Uti 1 ity Version 5,00.B168O copyright cj MicrosorFt Corp 1988-199B* Al 1 ri

6、ghts reserved.Iml /nologo /c /coff /Zi test.asmAssembling; test»asmL-i nk /nologo /DEBUG /DEB:LtG7YPE :C0FF /subsystem :CONSOLE test .obj|c ivA,bclil>chl'chi1 i s not recognized as an internal or external command) pperable program or batch file.c :*/bchl>t e stlie!Io,this is the first

7、 test program' he! Io,thi s i s the 干i /&t test proQrdJtifk :vbchl>这里输出两行消息主要是我在写这个最简单的程序的时候发现他不换行,于是我在数据定义后面我加了 “ 0ah, 0dh",呵呵,就是回车换行的十六进制表示,你也可以用其他方法试试, 程序就不多解释了,后面会有更多的解释,不过你一定要走到这以步,才能进行下一章。2.深入理解汇编语言的数据整数常量及变量,先看一段很简单的汇编程序:.386.model flat,stdcalloption casemap:none includelibmsv

8、crt.libprintf proto C :VARARG .datamsg1 db .code start:callretmain proc local localPRICE EQU 30 "total=%d",0dh,0ah,0mainnum:dwordtotal:dwordmovnum,10moveax,numimuleax,eax,PRICEmovtotal,eaxpushoffset msg1callprintfaddesp,4ret mainendpend start 程序的意思很简单就是在屏幕上打印出某个东西的价格,如过要你拿笔和纸算,拿你肯定很快就能算出来,

9、但你让电脑怎么算呢?当电脑执行到第一个语句的时候,也就是num=10,它就把 10 放到某个地方并且记住这个值,寄存器或者内存,呵呵,它也就这两个地方,为 什么要这么做呢?因为后面要用它来计算啊,为了算出这个值,电脑好的办法就是放在它的内存里,为什么不是寄存器?因为寄存器太少了,就那么几个,呵呵,所以了它就把10 存在一个叫num 的内存里,注意了哦,num 是程序里的变量名,是存中里的一个位置的名称,它的值是10,你可能会问,不起名不行么?行,等下在调试器中你看到的就是没名的。来看看它在调试器中的样子:Select cmd to cdlb.ue - cdb -2 C:Wbch2ch2-1k:

10、h2-155pushebpPO4O1CX)78becirrov&p,0040100983c4fBaddesp#orrrpFFF8hb04010OcC?45fcOaOOOOODmovdword ptr &bp-4,OAh304010138b45fcEVeaxTdword ptr ebp-4304010166bc01eimuleax,eax,lEh004010198945fBrrovdword ptr ebp-8 , eaxb040101c6SOO304000pushoffset ch2_1!_NULL_IMP0RT_DESCRIPTOE-rf)xf88 (00403000)J04

11、01021eB06000000cal 1ch2_l<pri ntf (Q04O1O3C)0040102683C404add日5PE:"j-4ulu2?C91 eavec3retP :000>num变成了 ebp-4 了,现在你想象有个几千行的程序如果都用ebp-4这样的名字的话,那我们会疯的,所以汇编程序就让我们给程序里面的变量起个直观的名字,而不是用具体的数字去让你去记住变量内存的位置。程序中imul eax,eax,1eh中的1eh就是个整形常量,也就是30.现在你应该对常量和变量有点感觉了吧。再看个例子:.386.model flat,stdcalloption c

12、asemap:noneincludelib msvcrt.libprintf proto C :VARARG .dataadb12hbdw1234hc1dd12345678hmsg1db "the number is=%xh",0dh,0ah,0.code start: call main retmain procmov al,acbwcwdepusheaxpushoffsetmsg1callprintfaddesp,8movax,wordptr acwdepusheaxpushoffset msg1callprintfaddesp,8moveax,dword ptr ap

13、usheaxpushoffset msg1callprintfaddsp,8retmainendpend start首先,你得想a, b, c1 三个变量在程序中到底是怎么存的,是12 12 34 12 34 56 78 ,还是 78 56 34 12 34 12 12 呢?呵呵,用调试器载入程序看看就知道了:004030000040310 D0040-320 00040330 000403JO 0040350 0040360 J'J04Q370 D:000> d 00403000 04Q3010 0403020 004030300040304000403050 0403060

14、0403070?7?77?7777?”777777777?77?,?77 79 7777 77 77 g 77 ? 77 77 77 77 77 77 77 77 77 0040300012 34 12 78 5665 71 20 69 73 00 QQ OQ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 QO 00 00 00 00 00 00 00 00 00? ? ?-? ? ? ? 77-7? "?77 77 77-77 77 77 ? 7?-? ?77 77 77-77 号今 77 77 77-7 7777 77 77

15、-77 77 77 77 ?-77 7734 12 74-68 65 3d 25 7&-68 Od 00 00 00-00 00 00 00 00-00' OO DO 00 00-00 OO 00 00 00-00 00 00 00 00-00 00 00 00 00-00 QO? ? ? ? ” ?"? 77 77 ? ?- 7? ?77 77 77 77 77 77 77 77 77 ? ? ? ¥* *>? 77 77 号号¥¥ 77 ?7 77 79- 77 77 77 77 77 77 77 77 77 77 77 77

16、77 7720 20 6e 75 6d 62 oa oo oo oo aa oo 00 00 QO 001 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00?"?77777?7 ?777?777777777777777?77777777?777777777777,777777777.4.xV4-t:he numb er i g=%xh.cmdl to cdb.exe - cdb -2 C:lcwblch2k:h2-3V:h2-3* ERROR:

17、 Symbol file could not be found. Defaulted to export symtols for ntdl1.dll - ntdl 11 'DbflBreakPoi nt: 7c90120e ccfrrt 3b:0005 g MexentryModLoad: 5cb7OOOO 5cb96000C :WIND0WS5ystem325himEng. dl 1eax=0CXXX)000 已bx=7千千dFOQQ ecx=0013ffbO edx=7c90e514 esi =00000000 edi =0(X)00000ei p =00401000 esp=00

18、13ffc4 ebp=C|C|13fffO iopl =0nv up ei pl zr na pe nccs=aoib 55=0023 dis =0023 es=OO23 fs=4)O3b gs=0000曰fl =000 0口 246台台育 WARNING: Unable to verify checksum for ch2-3 B exech2L3! start:00401000 ego10QOOOOcall ch2_3'main (00401006)D:000> teax00000000 ebx»7ffdZOOO eex>0013ffbD edx"7

19、c90e514 esi "OOOOOOOQ edH "00000000ei p-00401006 e5p=0013ffcO ebp=OO13fffO iopl=0nv up ei pl zr na pe nccs=001b 55=0023 ds=C»23 es=OO23 fs=<K)3b g5=0000ef 1l=DDQQ0246ch2_3 Imai n:00401006 a000304000 rrov al,byte ptr ch2_31_NULL_IMPORT_DESCRIPTORDxf88 (0040300D)| ds :0023 :00403000=

20、12D:000> d 0040300:000>哈哈,看到了没,正确的是这个:00403000:还有就是这个程序打印的三个结果又是什么呢?是12 34 12 78 56 34 12 74-68 ,这是为什么?12h 和 0012h 和 00000012h 吗?如果是,那你就错了哦,应该是:the number is=12h thenumber is=3412h the number is=78123412h呵呵,首先,你得明白这三个你定义的数据在内存是怎么存的,一个原则就是你定义的数据的高位存在内存中的高字节地址,你定义的第二个数据:1234h,高位字节是12吧,低位字节是34吧,所

21、以编译器它先存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

22、里面是什么值,扩展后eax的值还是等于 ax中的值。然后pusheax,和push offset msg1, call printf就是调用c语言库函数 printf打印消息, 就相当于c语言里面的:printf("the number is=%xhn",a);下面的和这段一样,我就不写废话 了。如果面对的是有符号数,那就得用 movsx 了,当然还有其他指令,后面再介绍。浮点数:在计算机内部,浮点数是以二进制表示的,所以,要先转换为二进制浮点数,转换分两部,整数部分的装换,采用“除 2取余法”,小数部分的装换,采用“乘 2取整法”,例如19.2, 先将19转换成二进制:1

23、0011,然后将0.2转换成二进制:001100110011,它是个无穷循环小数,然后就是规格化,分三种情况:如果定义的数据类型是dword或者是real4,那么符号位占一位,阶码占8位,位数占23位,总共是32位,如果定义的类型是qword或real8, 那么符号位占一位,阶码占 11 位, 位数占 52 位, 总共 64位, 如果定义的类型是real10或者是 tword ,那么阶码占15 位,位数占64 位,符号位占一位,总共80 位。怎么算阶码呢?如果是32 位,就将阶码加上127,然后转换成二进制,如果是64 位,就加上1023,如果是 80 位,就加上16383。我们看看怎么将19

24、.2转换成 32 位的二进制浮点数:首先将19转换成二进制:10011,然后将0.2转换成二进制:001100110011 ,整理成32 位 就 是 :10011 ,001100110011001100110011001 。 然 后 规 格 化 为 :1 ,0011001100110011001100110011001x2 的 4 次方,阶码为127 加 4 等于 131: 10000011。所以当浮点数19.2 表示为三种不同的数据类型为:32 位(dword, real4) : 0, 10000011, 001100110011001100110164 位 ( qword , real8

25、):0,100000000011,001100110011001100110011001100110011001100110011001180位:0,100000000000011,001100110011001100110011001100110011001100110011001100110011001100110011。转换成 16 进制就是4199999Ah , 40333333 33333333 h, 403999999999999999ah。然后我们yong 程序来验证一下对不对。例子如下:.386.model flat,stdcall option casemap:noneinc

26、ludelibmsvcrt.libprintf proto C :VARARG .dataf1 real419.2f2 real819.2f3 real10 19.2msg1 db "the floating number is=%g",0dh,0ah,0 .codestart: call main retmain proclocal f:real8fld dword ptr f1 fstp fpush dword ptr f+4 push dword ptr f+8push offset msg1call printfadd esp,12push dword ptr f2

27、+4push dword ptr f2push dword ptr offset msglcall printfadd esp,12fld f3fstp qword ptr fpush dword ptr f+4push dword ptr f+8push offset msglcall printfadd esp,12retmainendpend start程序很简单,就是分别在屏幕上打印三个浮点值,如下图:f cmd to masm32keMethe floati ng number i s-19.2the f Iflati rig number* i s = 19.2the floati

28、 ng nLirnber i .2c :vA.bdi2ch2-25nmaktMicrosoft (R) Program Maintenance Utility Version 5.00.8168.0Copyright fCj MicrosarFt Ccrp 1933-1998. Al 1 rights reserved.ml /c /coff /Zi ch2-2*asmMi crosoft R) Macro AsscmLl er* Version 6.14, S444Copyri ght 匕。Mi crosoft Corp 1981-1997. Al 1 ri ghts reserved.As

29、sembling: ch2-2.asmLink /tEEUG /DEBUGTYPE:COFF /subsystem:CONSOLE chZ-Z.objMi crosoft (R) Increm&iTtal Li nker Version 5,12.8078Copyright 匚Microsolit Corp 1592-199E* Al 1 rights reserved.|C ;wbch2ch2-2>nmakeVersion 5.00,81d3.0 rights reserved.Version 3,00<8163.0 rights reserved*riicrosoft

30、(R) Program Manntenance Uti 11tyfcopyright Microsoft Ccrp 1988-199B. Al 1cli2-2.exe' is up-to-darteIl ! wbe h 2c h 2 - 2 > nmak ?l*1i erc5oft R) Program Maintenance Uti 11ty topyright U Microsoft Corp 19&8-1998. Al 1ch2-2.exe1 is up-to-dateC ivA.bc h 2ch2-2>ch2-2the floating number 15=

31、19.2the fIcating number i s=19.2the floati ng number i 5=19.2在这里我要说明下,我只有把32 位和 80 位的转换为64 位的,才能打印成功,这可能是库函数 printf 的原因,怎么转换呢?32 位浮点转换64 位浮点:首先得借助一个64 位的浮点局部变量:localf:real8flddword ptr f1fstpf第一句定义了f 位一个 64 位的浮点局部变量,第二句就是把32 位浮点数转换为80 位的,然后第三句就是把80 位的转换位64 位的。80 位浮点转换位64 位浮点数:同样借助一个64 位的浮点局部变量:fldf3

32、fstpqword ptr f第二句就是把80 位的浮点转换位60 位的。但是这两句怎么解释呢:push dword ptr f2+4push dword ptr f2为什么要先把f2 的高 4 位字节入栈呢?好,我们先来看看这个数转换成64 位的 16 进制为:40333333 33333333h ,前面我说了高低对应原则,那么这个 64位的16进制在内存中高 4字节地址应该存 40333333h,也就是存它的高4字节,然后是33333333h,但是,呵呵,在堆栈中的地址是从高往低增长的,所以我们应该先把这个数的高四字节入栈,也就是 40333333h,怎么在内存中得到这高4字节呢?就是从

33、f2+4 处压入 4 字节就可以了,然后就是低4 字节入栈。如果还没理解,用cdb 调试一下就清楚了。浮点与整数之间的转换:先看例子成ch2-4:.386.model flat,stdcalloption casemap:noneincludelibmsvcrt.lib printf proto C :VARARG .dataf1 real819.2f2 dword 20msg1db "the floating to int number is=%d",0dh,0ah,0msg2db "the int to floating number is=%f",

34、0dh,0ah,0.codestart:call mainretmain proclocal f:real8fld f1fistp dword ptr f push dword ptr f push offset msg1 call printfadd esp,8fild f2 fstp fpush dword ptr f+4 push dword ptr f+8 push offset msg2 call printfadd esp,12retmainendp end start 运行结果为:f cmd to masm32,exeIC :wbch2cli2-45 nmak eFlMi cro

35、sof-t R) Progr,ani titenafics Cti 11ty Copyright Cc5 Microsoft Corp 1988-199E. Al 1Version G.CQ.613.0 riqhts reserved.1 ch2-4.exe1 i5 up-to-dateMicrosoft CR) Prograin Maintenance Ut11 ity Copyright (CJ MicrosorFt Corp 1388-199G. Al 1Version 6,00.8163,0 vights reserved4'ch2-4*ex&1 i s up-to-d

36、arteMi crosoft CR) Program Maintenance UtilityCopyright Microsoft Corp 1988-199E* Al 1Version 6.00.E168.O right与 reserved.'ch2-4,exe' is up-to-dateMi crosoft (良Program Maintenance Utility topyright HicrosorFt Corp 13B3-1996» Al 1Version 6,00.8168.0 rights reserved»'2-4+ exe'

37、; i s up-to-datet :yA.tic li 2ch2 -4 > ninaksMicrosoft (R) Program Maintenance Lti1ity topyright (Cj Microsoft Corp 1988-1996, Al 1Version 6,00.E168»Orights reservedT'ch2-4 + exe * is up-to-dateC :vAbcli2ch2-4> ch2-1the float!ng to int nuntoer i5=19the int to floating number is=20.000

38、000":yAbkha浮点数转换成整数:fld flfistp word ptr f首先我们还是借助了一个64位的局部变量,先把浮点数装入浮点寄存器,然后用装换整行的指令变成整数再存入一个局部变量就行了。整数转换成浮点数:fild f2fstp f先把整数用装换指令装入浮点寄存器,然后把浮点数存到一个局部变量就可以了。我在后面会详细说名浮点数的运算和浮点寄存器的。字符与字符串常量:怎么定义他们?他们是以什么形式存在计算机中?首先我们怎么在汇编中定义他们呢:先看看例子ch2-5:.386.model flat,stdcalloption casemap:noneincludelibms

39、vcrt.libprintf proto C :VARARG.datastr1 db 'this is a string test',0ah,0dh,0str2 db "this is a string test",0ah,0dh,0.codestart:call mainretmain procmov eax, offset str1push offset str2call printfadd esp,4push offset str1call printfadd esp,4retmainendpend start程序就是在屏幕上打印两行消息,下面是运行结

40、果:I-回Xcmd to masm32,exet :>set i ncl udE»c :ina5fli3 2i ncl udl&C iXProgram Fi 1 esMi crosoft Vi sual Studi oVC98 Inc 1 ude;C :PrQflram Fl les11i crosoft Vi sual 5tuchnVC98MlFC工nul uck;>set 1 i b- c; ma5m3 2 i bk:>set path = c:ma5in3?Lir;c:oracleora92bi n;C:Progrm Ft 1 es0racl14 ?

41、KbinjC: WI MDOWSey £t&m32;C :WI MDOWS; C :邓工 NDOWSSy st &m3 2Wb em;C:P rogram File sCo rrmon Fi 1 esGTK240bi n;C :Program FilEsALrtodeskDWG TrueView;C:Program Fi 1 es rli crosoft SQL ScrvepMTool sbi rir; C iProgram Fil crosoft Visual Studi aCotn monToolsWi nNT;C:Pncigram Fi 1 eslicrosof

42、t Visual StuclioCoiTmonVSDev98Bin;C:P roqr arn Fi 1 c 与、司 i 二广口 三口十七 Ui 三ua" ' izudi 口1_口口1?汇 n 1 口口 1 弓;t_ : Pr 口 三广 13rl F i 1 已 占、M 1 匚口与 口干七 J i s lial StudioVC98bi n;D :StcrmIIGodec;D :StonnIIC :icd C :wt*Vh2ch2-5t :bc h 2ch2 - 5 i nmak trlicrosoft (R) Program Maintenance Utility Versi

43、on 5,00.S168,0 popyright Jcj Microsof± Corp 1988-19984 Al 1 rights reserved.Iml /nologo /c /coff /Zi ch?-5.asmA556mbli ng; ch2-5»asmLi nk /nolo go /DEBUG /DEBLkTTYPE 二 COFF /subsystem :CONSOLE ch2-5.obj|c :vA,bch2ch2- 5>ch2-5this is a string testrthi5 i5 a string test|c:心匕二村2"2-5&g

44、t;然后我们用cdb调试器看看定义的那两个字符串变量在内存中到底是怎么样的:Executbl e searchHodLoad: HodLoad: ModLoad: ModLoad:OOOC'000 7C9O0OOO ?E800000 77C10000path i 00404000 7c9b20007匚转5000 77C68000(d68.2e8) : Break instructionntdl 1 »d!1C :WIND0WSsystem32kernel32r dl 1C:WINDOWSsy5tem32M5VCRT,dl1 exception - code 80000003

45、(first chance)eax=0O251eb4 ebx=7ffdaOOO ecx=OOO0OOO4 edx=00000010 esi=O0251f48 edi=00251eb4ei p=7c9O120e esp=0013f b2O ebp=0013f c94 iopl =0riv up ei pl nz na po nccs=001b 55=0023 ds=0O2J es-QQ23 fs=O03b gs=0000efl=00000202* ERROR: Symbol fi1e could not he found. Defaulted to export symbols for ntdl

46、1.dllntdl1'DbgBreakPoint: 7c90120e cc :D0O> g fl'texentry,i ntModLoad: ScbZOOOO 5cb96Q00 C:WIND0WSsy5tem32Shim£ng,dl1eax=0(XXXX)a0 ebx-7ffdaOO0 ecx=0013ffb0 edx=7E90e514 esi QQQQOOOO edi=QQQQQ0QQ ei p=(XM0100Q esp=0013izfc4 ebp=0013fff0 iopl =0 nv up ei pl zr na pe nc cs=001b 55=0023

47、 ds=0023 es=OO23 fs=003b gs=OOOO efl=00000246 * WARNING: Unable to verify checksum for ch2-5.exech2_5!start:00401000 e801000000cal 1ch?_5 'mai n t00401006)0;OQOi teax.ooocnoao ebx-7ffdttOOO ecx-OQ13ffbO edK-?c90e514 tsi-OOOOOOOO edi-00000000 ei pa(XM01006 esp»0013ffc0 ebp»0013fff0 iopl

48、 >0nv up ei pl zr nd pe nccs»001b S5-O023 ds«OO23 esOO23 fs=003b gs=0000ef >00000 24 6ch2_5 Fmavn:0401006b800304000mziveax,offset ch2_51_NULL_IMPQRT_DESCRIPTDR+Oxf88 (0003000)0:000> d 00403000 00403010 00403020 00403030 00403040 00403050 00403060 00403070 b:ooo>_y 5 3 0 0 0 0 0

49、O 6 6 7 0 0 0 0 0 O084000000 rj67200 0 00 o4401000002600000 o20-61 00-746-20 00-00 00-00 DO-00 00-00 00-00696769 73 20S 0d 0000 00 0000 00 0000 00 0000 00 0000 00 00thi s i 5 a stringtestB >.thi s i sa stri ng t.ca cmdl to cdb.exe - cdb -2 C:wblch2lch2-5ch2-5恩,它们是以asii码的形式存在的。其他的数据类型我会在下面的各个章节会随着

50、编程的算法和调试一起讲解。3:顺序程序设计汇编语言的顺序编程比较好理解,就是在编程的时候没有跳转,没有循环,看看例子ch3-1:例ch3-1 :输入三角形的边长,求三角形的面积。我假设输入的三边长都是能构成三角形的,求三角形面积的公式为area= s(s-a)(s-b)(s-c)。s= (a+b+c) /2.这里要用到浮点指令,那就先回顾下浮点指令的用法:这里要加减乘除和平方根五种指令,由于Intel的浮点数据寄存器是种堆栈结构,我们要记住这一点。先看看数据传送指令:fld和fild , fst, fstp:fld源操作数,源操作数可以是浮点寄存器和内存,这个指令主要是把源操作数压入浮点寄存器

51、堆栈(其实就是 st0),如果源操作数是整数,那就用 fild。Fst和fstp是把st (0)浮点寄存器中的数弹出到目的操作数中,目的操作数可以为浮点寄存器和内存。加减法指令:fadd, faddp, fub , fsubp第一种形式:fadd目的操作数,源操作数。其中目的操作数,源操作数可以为浮点寄存器和内存。第二种形式:fadd源操作数,我本人比较喜欢这种,它不会把我脑海里的浮点寄存器的顺序弄乱,这种形式的源操作数只能是内存。减法指令同加法指令,就不多说了。乘除法指令:fmul , fdiv浮点的乘除法是不区分有符号和无符号数的,他们也有两种形式:fmul 目的操作数,源操作数和 fmu

52、l 源操作数这两种形式,第一种 操作数和源操作数可以为浮点寄存器和内存,但第二种源操作数值能为内存。平方根指令:fsqrt这个指令就一种形式就是fsqrt,就是把第0个浮点寄存器st0的值变成平方根值然后存在st0 中。再回到例题中,我们应该先算s值,然后再算平方根下面的值然后求平方根就行了。S值是三边长除以2,转换成浮点指令就是:fld a ;先把a值放到浮点寄存器 st0中 再就是 fadd b ;这个就是 a+b,结果存在 st0中 然后fadd c ;同上,结果存在st0 中现在算出了三边长的和,在除以 2就ok 了 fiv two;结果在st0中, 最后把st0里面的值用fstp s

53、存到s中就把s值算出来了。再来算根号下面的值,这里有乘法和减法,我们先算减法:fld sfsub, a;这个就是 s-a,结果在st0 里 再fld sfsub b;这个结果还是在 st0里, 但是上面那个s-a 已经被推到st( 1 )这个浮点堆栈了啊,记住了。再fld sfsub c;这个结果还是在 st0里, s-c的值在st (0)中,这里千万不能及乱了啊,下一步算乘法,先算s*( s-c) ,s*(s-a) *(s-b)最后算s*( s-a) *(s-b) *mul s;果在 stOlifmul st(0), st( 1 )这一步是算 一步是算s-a)fmul st( 0) , st

54、( 2) ,那么 s-a 被推到st( 2)了,s-b 被推到st(1)了,然后把s* (s-a) * (s-b) * (s-a)的结果再求平方根fsqrt再把这个平方根的值弹出到area中。这是按照上面的想法写出的程序:.386.model flat,stdcalloption casemap:noneincludelibmsvcrt.libprintfproto C :VARARGscanfproto C :VARARG.datamsg1db "%f,%f,%f",0msg2db "area=%7.2f",0ah,0dh,0msg3db "

55、please input three floating numbers",0ah,0dh,0two real42.0.codestart:call main retmain proclocal a:real4local b:real4local c1:real4 local s:real4 local area:real8pushoffset msg3 call printf add esp,4lea eax,c1 pusheax lea eax,b pusheax lea eax,a pusheaxpushoffset msg1 call scanfadd esp,16fld a

56、fadd b fadd c1 fdiv two fstp sfsub a fsub b fsub c1fmul sfmul st,st(1) fmul st,st(2) fsqrtfstp area pushdword ptr area+8 pushdword ptr area+4 pushoffset msg2call printfadd esp,12retmainendpend start编译运行:下面是结果:但是出乎意料哦,错了,怎么办呢?你发现什么问题了没?那只有调试看看了,用cdb -2 C:wbch3ch3-1ch3-1打开程序然后逐步调试看看,当跟踪到下面这句是就发现 有问题了:f cmd to m<jsm32.exeTpcw«027F: rn 53

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论