Win32汇编--Win32汇编的高级语法

Win32汇编的高级语法
以前高级语言和汇编的最大差别就是条件测试、分支和循环等高级语法。
高级编程语言(C、C++、DELPHI等)中,程序员可以方便地用类似于if,case,loop 和 while 等语句来构成程序的结构流程,不仅条理清楚、一目了然,而且维护性相当好。
而汇编程序呢?
我们来做一下实验,顺便教大家用VS2008编译C的程序。。。。。。

经过刚才的对比,是不是觉得汇编的代码就像封建女友的思想一样,让你十分难堪和惧怕?
现在好了,随着科技的发展。。。MASM中新引入了一系列的伪指令,涉及条件测试、分支和循环语句。
利用它们,汇编语言有了和高级语言一样的结构,配合对局部变量和调用参数等高级语言中觉元素的支持,为使用Win32汇编编写大规模的应用程序奠定了基础。

MASM条件测试的基本表达式是:
       寄存器或变量 操作符 操作数
两个以上的表达式可以用逻辑运算符连接:
       (表达式1) 逻辑运算符 (表达式2) 。。。

x == 3                 ; x等于3
eax != 3              ; eax不等于3
(y>=3) && ebx     ; y大于等于3且ebx为非零值
(z&1) ||!eax        ; 自己挑战下 

细心的读者一定会发现,MASM的条件测试采用的是和C语言相同的语法。

如!和&是对变量的操作符(取反和与操作),||和&&是表达式结果之间的逻辑与和逻辑或,而==、!=、>、<等是比较符。

同样,对于不含比较符的单个变量或寄存器,MASM也是保留着将所有非零认为是真,零值认为是假的底线。

MASM的条件测试语句有几个限制,首先是表达式的左边只能是变量或寄存器,不能为常数;其次表达的两边不能同时为变量,但可以同时是寄存器。
这些限制主要来自于80x86指令的局限,因为条件测试伪操作符只是简单地把每个表达式翻译成cmp或test指令,80x86的指令集中没有cmp 0,eax之类的指令,同时也不允许直接操作两个内存中的数,所以对这两个限制是很好理解的。

除了这些和高级语言类似的条件测试伪操作,汇编语言还有特殊的要求,就是程序中常常要根据系统标志寄存器中的各种标志位来做条件跳转。

所以高级汇编又增加了以下一些标志位的状态指示,它们本身相当于一个表达式:
CARRY?                表示Carry位(进位)是否置位
    OVERFLOW?        表示Overflow位(溢出位)是否置位
    PARITY?               表示Parity位(奇偶位)是否置位
    SIGN?                  表示Sign位(符号位)是否置位
    ZERO?                  表示Zero位(零位)是否置位

要测试eax等于ebx且同时ZERO位置1,条件表达式可以写为:
       (eax == ebx) && ZERO?
要测试eax等ebx同时Zero位清零,条件表达式可以写为:
       (eax == ebx) && !ZERO?
和C语言的条件测试同样,MASM的条件测试伪指令并不会改变被测试的变量或寄存器的值,只是进行测试而已,到最后它会被编译器翻译成类似于cmp或test之类的比较或位测试指令。


分支语句
分支语句用来根据条件表达式测试的真假执行不同的代码模块,MASM中的分支语句的语法如下

.if 条件表达式1
              表达式1为“真”时执行的指令
       [.elseif 条件表达式2]
              表达式2为“真”时执行的指令
       …… ……
       [.else]
              所有表达式为“否”时执行的指令
       .endif
注意:
使用.if/.else/.endif构成分支伪指令的时候,不要漏写前面的小数点。

if/else/endif是宏汇编中条件汇编宏操作的伪操作指令,作用是根据条件决定在最后的可执行文件中包不包括某一段代码。

这和.if/.else/.endif构成分支的伪指令完全是两回事情,尽管他们很像。
示例:example


循环语句
循环是重复执行的一组指令,MASM的循环伪指令可以根据条件表达式的真假来控制循环是否继续,也可以在循环体中直接退出,使用循环的语法是:

.while      条件测试表达式
              指令
              [.break [.if 退出条件]]
              [.continue]
       .endw

.while/.endw 循环首先判断条件测试表达式,如果结果是真,则执行循环体内的指令,结束后再回到.while 处判断表达式,如此往复,一直到表达式结果为假为止。

可以使用.break伪指令强制退出循环,如果.break 伪指令后面跟一个.if测试伪指令的话,那么当退出条件为真时才执行.break 伪指令。
在循环体中也可以用.continue伪指令忽略以后的指令,遇到.continue伪指令时,不管下面还有没有其他循环体中的指令,都会直接回到循环头部开始执行。

演示1:example
演示2:example

.repeat
              指令
              [.break [.if 退出条件]]
              [.continue]
       .until 条件测试表达式 (或.untilcxz [条件测试表达式])
.repeat/.until循环首先执行一遍循环体内的指令,然后再判断条件测试表达式,如果结果为真的话,就退出循环,如果为假,则返回.repeat处继续循环,可以看出,.repeat/.until不管表达式的值如何,至少会执行一遍循环体内的指令。

题目:将while部分用repeat实践一下。










posted on 2015-08-19 17:58  木屐  阅读(476)  评论(0编辑  收藏  举报

导航