上一题下一题
跳转到
 
 
  世界如此多姿,发展如此迅速,窥一斑未必还能知全豹。但正如万花筒一样,每一个管窥都色彩斑斓。  
 
 
  知识通道 | 学习首页 | 教师首页 | PK首页 | 知识创造首页 | 企业首页 | 登录
 
本文对应知识领域
程序解释
作者:未知 申领版权
2010年12月12日 共有 1922 次访问 【添加到收藏夹】 【我要附加题目
受欢迎度:

    程序解释
    .386
    这是一个汇编语言伪指令,他告诉编译器我们的程序是使用80386指令集编写的。您还可以使用 .486、.586, 但最安全的还是使用.386。对于每一种CPU有两套几乎功能相同伪指令: .386/.386P、 486/.486P、 586/.586P。 带P的指令标明您的程序中可以用特权级指令。特权级指令是保留给操作系统的,如虚拟设备驱动程序。在大多数时间,您的程序都无须运行在RING 0层,故用不带后缀P的伪指令已足够了。
    
    .MODEL FLAT,STDCALL
    .MODEL 是用来指定内存模式的伪指令,在Win32下,只有一种内存模型,那就是FLAT。 STDCALL 告诉编译器参数的传递约定。参数的传递约定是指参数传达时的顺序(从左到右或从右到左)和由谁恢复堆栈指针(调用者或被调用者)。在Win16下有两种约定:C 和 PASCAL。C 约定规定参数传递顺序是从右到左,即最右边的参数最先压栈,由调用者恢复堆栈指针。
    例如:为调用函数 foo ( int first_param, int second_param, int third_param ); 按C约定的汇编代码应该是这样的:
    push [third_param]
    push [second_param]
    push [first_param]
    call foo
    add esp, 3 * 4 ;调用者自己恢复堆栈指针
    PASCAL约定和C约定正好相反,它规定参数是从左向右传递,由被调用者恢复堆栈。Win16采用了PASCAL约定, 因为PASCAL约定产生的代码量要小。当不知道参数的个数时,C约定特别有用。如在函数wsprintf () 中, wsprintf预先并不知道要传递几个参数,所以它不知道如何恢复堆栈。STDCALL是C约定和PASCAL约定的混合体,它规定参数的传递是从右到左,恢复堆栈的工作交由被调用者。
    option casemap:none 一句的意思是告诉 MASM 要区分标号的大小写,譬如:start 和 START 是不同的。
    
    include ...,跟在其后的文件名所指定的文件在编译时将"插"在该处。当MASM处理到语句 include \masm\include\windows.inc 时,它就会打开文件夹\MASM32\include 中的文件windows.inc,这和您把整个文件都粘贴到您的源程序中的效果是一样的。includelib 伪指令和 include 不同,它仅仅是告诉编译器您的程序引用了哪个库。当编译器处理到该指令时会在生成的目标文件中插入链接命令告诉链接器链入什么库。当然您还可以通过在链接器的命令行指定引入库名称的方法来达到和用includelib指令相同的目的。
    
    .DATA .DATA? .CONST .CODE
    上面的四个伪指令是"分段"(SECTION)伪指令。Win32下没有"段"(SEGMENT)的概念,但是您可以把您的程序分成不同的"分段", 一个"分段"的开始即是上一个"分段"的结束。WIN32中只有两种性质的"分段":DATA和CODE。
    其中DATA"分段"又分为三种:
    .DATA 其中包括已初始化的数据。
    .DATA? 其中包括未初始化的数据。比如有时您仅想预先分配一些内存但并不想指定初始值。使用未初始化的数据的优点是它不占据可执行文件的大小。
    .CONST 其中包括常量定义。这些常量在程序运行过程中是不能更改的。 应用程序并不需要以上所有的三个"分段", 可以根据需要进行定义。 
    .CODE 这是代码"分段"。 
    
    start:
    invoke MessageBox,NULL,addr MsgBoxText,addr MsgBoxCaption,MB_OK
    invoke ExitProcess, NULL 
    end start
    应用程序的执行是从 END 定义的标识符后的第一条语句开始的。在上面的框架程序中就是从 START 开始。程序逐条语句执行一直到遇到 JMP,JNE,JE,RET 等跳转指令。这些跳转指令将把执行权转移到其他语句上,若程序要退出 Windows,则必须调用函数 ExitProcess。
    ExitProcess proto uExitCode:DWORD
    上面一行是函数原型。函数原型会告诉编译器和链接器该函数的属性,这样在编译和链接时,编译器和链接器就会作相关的类型检查。 函数的原型定义如下: 
    FunctionName PROTO [ParameterName]:DataType,[ParameterName]:DataType,... 
    简言之,就是在函数名后加伪指令PROTO,再跟一串由逗号相隔的数据类型链表。在前面的 ExitProcess 定义中,该函数有一个 DWORD 类型的参数。当您使用高层调用语句 INVOKE 时,使用函数原型定义特别有用,可以简单地认为 INVOKE 是一个有参数类型检查的调用语句。譬如:
    call ExitProcess
    若您事先没把一个DWORD类型参数压入堆栈,编译器和链接器都不会报错,但毫无疑问,在您的程序运行时将引起崩溃。但是,当您这样写:
    invoke ExitProcess
    连接器将报错提醒您忘记压入一个 DWORD 类型参数。所以我建议您用 INVOKE 指令而不是CALL去调用一个函数。INVOKE 的语法如下:
    INVOKE expression [,arguments]
    expression 既可以是一个函数名也可以是一个函数指针。参数由逗号隔开。大多数API函数的原型放在头文件中。这些头文件的扩展名为 INC,函数名和 DLL 中的函数名相同。现在回到ExitProcess 函数,参数uExitCode 是应用程序结束时传递 Windows 的。 可以这样写: 
    invoke ExitProcess,0 
    把这一行放到程序结束的地方,这个应用程序就会立即退出 Windows。
    对话框函数的原型如下:
    MessageBox PROTO hwnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD 
    l hWnd 是父窗口的句柄。句柄代表您引用的窗口的一个地址指针。它的值对您编 Windows 程序并不重要,您只要知道它代表一个窗口。当您要对窗口做任何操作时,必须要引用该窗口的指针。 
    l lpText 是指向您要显示的文本的指针。指向文本串的指针事实上就是文本串的首地址。 
    l lpCaption 是指向您要显示的对话框的标题文本串指针。 
    l uType 是显示在对话框窗口上的小图标的类型。
    我们在.DATA"分段"定义了两个NULL结尾的字符串。我们用了两个常量:NULL 和 MB_OK。这些常量在windows.inc 文件中有定义,使用常量使得您的程序有较好的可读性。 addr  操作符用来把标号的地址传递给被调用的函数,它只能用在 invoke 语句中,譬如您不能用它来把标号的地址赋给寄存器或变量,如果想这样做则要用 offset 操作符。在 offset 和 addr 之间有如下区别:
    1) addr不可以处理向前引用,offset则能。所谓向前引用是指:标号的定义是在invoke 语句之后,譬如在如下的例子:
    invoke MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK
    
    ...... 
    
    MsgBoxCaption db "Iczelion Tutorial No.2",0
    MsgBoxText db "Win32 Assembly is Great!",0
    
    如果您是用 addr 而不是 offset 的话,那 MASM 就会报错。 
    2) addr可以处理局部变量而 offset 则不能。局部变量只是在运行时在堆栈中分配内存空间。而 offset 则是在编译时由编译器解释,这显然不能用offset 在运行时来分配内存空间。编译器对 addr 的处理是先检查处理的是全局还是局部变量,若是全局变量则把其地址放到目标文件中,这一点和 offset 相同,若是局部变量,就在执行 invoke 语句前产生如下指令序列: 
    lea eax, LocalVar
    push eax
    因为lea指令能够在运行时决定标号的有效地址,所以有了上述指令序列,就可以保证 invoke 的正确执行了。 
    
    3.编译:
    保存例子,取名为hello.asm。把 ml.exe 的路径放到 PATH 环境变量中,键入下面一行 进行编译:
    ml /c /coff /Cp hello.asm (注意:命令行参数大小写是有区别的)
    l /c 是告诉MASM只编译不链接。这主要是考虑到在链接前您可能还有其他工作要做。 
    l /coff 告诉MASM产生的目标文件用 coff 格式。MASM 的 coff 格式是COFF(Common Object File Format:通用目标文件格式) 格式的一种变体。在 UNIX 下的 COFF 格式又有不同。 
    l /Cp 告诉 MASM 不要更改用户定义的标识符的大小写。在.model 指令下加入 "option casemap:none" 语句,可达到同样的效果。 
    当您成功的编译了 hello.asm 后,编译器会产生 hello.obj 目标文件,目标文件和可执行文件只一步之遥,目标文件中包含了以二进制形式存在的指令和数据,比可执行文件相差的只是链接器加入的重定位信息。 
    好,我们来链接目标文件:
    link /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib hello.obj
    l /SUBSYSTEM:WINDOWS 告诉链接器可执行文件的运行平台 
    l /LIBPATH:〈path to import library〉 告诉链接器引入库的路径。 

    

 

相关新闻

什么是时间?
证券交易所定义、特征、功能
应收账款释义
高中化学基本概念
C语言复习习题-程序改错
C语言复习习题-简单程序
Win32汇编程序的结构和语法
实模式
单循环程序的设计方法

您可能对这些感兴趣  

干货分享|10本最受国外孩子喜爱的英文词典——上
从孩子的表现看父母的缺点!请家长对号入座,看看你是哪一类?
20条制作PPT的视觉原则
培训简史:培训者必知的历史轨迹
广田丰管理培训生人才培养调查报告
第4讲 作为上司的职业经理
第3讲 作为同事的职业经理
第2讲 作为下属的职业经理
第1讲 培养经理人的管理素养
酒店前台新员工上岗培训计划

题目筛选器
日期:
类型:
状态:
得分: <=
分类:
作者:
职业:
关键字:
搜索

 
 
 
  焦点事件
 
  知识体系
 
  职业列表
 
 
  最热文章
 
 
  最多引用文章
 
 
  最新文章
 
 
 
 
网站介绍 | 广告服务 | 招聘信息 | 保护隐私权 | 免责条款 | 法律顾问 | 意见反馈
版权所有 不得转载
沪ICP备 10203777 号 联系电话:021-54428255
  帮助提示    
《我的太学》是一种全新的应用,您在操作中遇到疑问或者问题,请拨打电话13564659895,15921448526。
《我的太学》