x86汇编_MASM的IF伪指令_笔记44

高级语言常见的if语句如下:

if(表达式1)
    语句1;
else  if(表达式2) 
    语句2;
else  if(表达式m) 
    语句m;
else
    语句n;

MASM的IF伪指令

MASM也有类似写法的伪指令,但汇编器会在后台生成CMP和条件跳转指令。使用与C++和JAVA相同的运算符 ( 比如:<、>、== 和 !=)。表达式在运行时计算。下面的例子给出了一些有效的条件,使用的是 32 位寄存器和变量:

eax > 10000h
val1 <= 100
val2 == eax
val3 != ebx

(eax > 0) && (eax > 10000h)
(val1 <= 100) || (val2 <= 100)
(val2 != ebx) && !CARRY?

所有的关系和逻辑运算符
运算符说明
expr1 == expr2若 expr1 等于 expr2,则返回“真”
expr1 != expr2若 expr1 不等于 expr2,则返回“真”
expr1 > expr2若 expr1 大于 expr2,则返回"真”
expr1 ≥ expr2若 expr1 大于等于 expr2,则返回“真”
expr1 < expr2若 expr1 小于 expr2,则返回“真”
expr1 ≤ expr2 若 expr1 小于等于 expr2,则返回“真”
!expr1 若 expr 为假,则返回“真”
expr1 expr2对 expr1 和 expr2 执行逻辑 AND 运算
expr1 || expr2对 1xprl 和 expr2 执行逻辑 OR 运算
expr1 & expr2对 expr1 和 expr2 执行按位 AND 运算
CARR1?若进位标志位置 11则返回“真”
OVERFLOW ?若溢出标志位置 1,则返回“真”
PARITY ?若奇偶标志位置 1,则返回“真”
SIGN ?若符号标志位置 1,则返回“真”
ZERO ? 若零标志位置 1,则返回“真”

在使用 MASM 条件伪指令之前,一定要彻底了解怎样用纯汇编语言的指令实现条件分支。此外,在包含条件伪指令的程序汇编中,要查看列表文件以确认 MASM 生成的代码确实是编程者所需要的。

有符号数和无符号数的比较

关于有符号数和无符号数的比较的问题,汇编器根据定义数据的伪指令属于无符号或者有符号,来确定当遇到if伪指令时要用有符号还是无符号的跳转指令。

定义内存数据时需要伪指令如:sdword、dword,当遇到用寄存器与内存数据比较时,可以借此确定用有符号或者无符号跳转指令。但是当遇到寄存器与寄存器的比较,汇编器就无法确定寄存器中的数值是有符号的还是无符号。

复合表达式

很多复合布尔表达式使用逻辑 OR 和 AND 运算符。用 .IF 伪指令时,符号 || 表示的是逻辑 OR 运算符。符号 && 表示的是逻辑 AND 运算符。

.IF expression1 || expression2
    statements
.ENDIF
.IF expression1 && expression2
    statements
.ENDIF

SetCursorPosition 示例

下例给出的 SetCursorPosition 过程,根据两个输入参数 DH 和 DL,执行范围检查。Y 坐标(DH)范围必须为 0〜24。X 坐标(DL)范围必须为 0〜79。不论发现哪个坐标超出范围,都显示一条错误消息:

SetCursorPosition PROC
; 设置光标位置
; 接收: DL = X坐标, DH = Y坐标
; 检查 DL 和 DH 的范围
; 返回:无
;------------------------------------------------
.data
BadXCoordMsg BYTE "X-Coordinate out of range!",0Dh,0Ah,0
BadYCoordMsg BYTE "Y-Coordinate out of range!",0Dh,0Ah,0
.code
    .IF (DL < 0) || (DL > 79)
       mov  edx,OFFSET BadXCoordMsg
       call WriteString
       jmp  quit
    .ENDIF
    .IF (DH < 0) || (DH > 24)
       mov  edx,OFFSET BadYCoordMsg
       call WriteString
       jmp  quit
    .ENDIF
    call Gotoxy
quit:
    ret
SetCursorPosition ENDP

MASM 对 SetCursorPosition 进行预处理时,生成代码如下:

.code
;.IF (dl < 0) || (dl > 79)
    cmp dl, OOOh
    jb @C0002
    cmp dl, 04Fh
    jbe @C0001
@C0002:
    mov edx,OFFSET BadXCoordMsg
    call WriteString
    jmp quit
;.ENDIF
@C0001:
;.IF (dh < 0) || (dh > 24)
    cmp dh, OOOh
    jb @COOO5
    cmp    dh, 018h
    jbe @C0004
@COOO5:
    mov edx,OFFSET BadYCoordMsg
    call WriteString
    jmp quit
;.ENDIF
@C0004:
    call Gotoxy
quit:
    ret

大学注册示例

假设有一个大学生想要进行课程注册。现在用两个条件来决定该生是否能注册:第一个条件是学生的平均成绩,范围为 0〜400,其中 400 是可能的最高成绩;第二个条件是学生期望获得的学分。可以使用多分支结构,包括 .IF、.ELSEIF 和 .ENDIF。示例如下。

.data
TRUE = 1
FALSE = 0
gradeAverage  WORD 275    ; 要检查的数值
credits       WORD 12     ; 要检查的数值
OkToRegister  BYTE ?
.code
main PROC
    mov OkToRegister,FALSE
    .IF gradeAverage > 350
       mov OkToRegister,TRUE
    .ELSEIF (gradeAverage > 250) && (credits <= 16)
       mov OkToRegister,TRUE
    .ELSEIF (credits <= 12)
       mov OkToRegister,TRUE
    .ENDIF

对应的汇编代码如下:

.386	
.model flat, stdcall
.stack 4096	
ExitProcess proto, dwExitcode:dword
include irvine32.inc

.data
true = 1
false = 0
gradeAverage  word 215    ; 要检查的数值
credits word 12     ; 要检查的数值
OkToRegister byte ?

.code
main proc
	nop
	mov byte ptr OkToRegister, false  ;false是一个立即数,默认为32位,此处用byte ptr。
	cmp gradeaverage, 350
	jbe @001
	jmp finish

	@001:
	cmp gradeaverage, 250
	jbe @002
	cmp credits, 16
	jbe finish

	@002:
	cmp credits, 12
	ja quit

	finish:
	mov byte ptr OkToRegister, true

	quit: ret
main endp

end main	

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值