信息安全之汇编语言学习(2)。。。。
高级语言特性
MASM 6.0引入高级语言的程序设计特性
条件控制伪指令
.IF .ELSE .ENDIF
循环控制伪指令
.WHILE .ENDW .REPEAT .UNTIL
过程声明和过程调用伪指令
.WHILE .ENDW .REPEAT .UNTIL
类似高级语言中IF、THEN、ELSE和ENDIF的相应功能
在汇编时要展开,自动生成相应的比较和条件转移指令序列,实现程序分支
.IF 条件表达式 ;条件为真(值为非0)
分支体 ;执行分支体
[ .ELSE ;前面IF条件为假
分支体 ;执行分支体 ]
.ENDIF ;分支结束
条件表达式中的操作符
例题
;单分支结构 多分支结构
.IF AX < 0 .IF ax==5
neg ax mov bx,ax
.ENDIF mov ax,0
mov result,ax .ELSE
dec ax
.ENDIF
;双分支结构(*汇编程序产生)
.IF ax==5
* cmp ax,05h
* jne @C0001
mov bx,ax
mov ax,0
.ELSE
* jmp @C0003
*@C0001: dec ax
.ENDIF
*@C0003:
对于条件表达式中的变量,若用DB、DW、DD定义时,则一律作为无符号数,若要进行有符号数,可以利用SBYTE,SWORD和 SDWORD来定义语句。
采用寄存器和常数进行比较时,默认也是无符号数,如果要当作有符号数,必须通过sbyte ptr 指明。
例题
.if sword ptr bx >= ax ;比较二者大小
mov tag,1
;第一分支体:条件满足,tag←1
.else
mov tag,0
;第二分支体:条件不满足,tag←0
.endif
.exit 0
循环控制伪指令
WHILE结构的循环控制伪指令
.WHILE 条件表达式 ;条件为真
循环体 ;执行循环体
.ENDW ;循环体结束
UNTIL结构的循环控制伪指令
.REPEAT ;重复执行循环体
循环体
.UNTIL 条件表达式 ;直到条件为真
例题:求1~100之和
;WHILE结构 ;UNTIL结构
xor ax, ax xor ax, ax
mov cx,100 mov cx,100
.while cx!=0 .repeat
add ax,cx add ax,cx
dec cx dec cx
.endw .until cx==0
mov sum,ax .until cx==0
下部分总结构
mov cx,100
xor ax,ax
lea bx,array
.repeat
.if sword ptr [bx] >= 0
add ax,[bx]
.else
.break
.endif
inc bx
inc bx
.untilcxz
mov result,ax
** 过程声明和过程调用伪指令
**
过程名 PROC 调用距离 语言类型 作用范围 <起始参数>
USES 寄存器列表, 参数:类型
LOCAL 参数表
… ;汇编语言语句
过程名 ENDP
**要调用带参数过程定义的过程,不应采用CALL指令,因为比较烦琐
应该采用过程调用伪指令INVOKE
使用INVOKE伪指令的前提是需要用PROTO伪指令对过程进行声明
过程声明伪指令:用于事先声明过程的结构
过程名 PROTO 调用距离 语言类型, 参数:类型
过程调用伪指令
INVOKE过程名,参数,…
汇编程序
.model small
checksumd PROTO c,:word,:word ;声明过程
.stack
.data
array db 12h,25h,0f0h,0a3h,3
db 68h,71h,0cah,0ffh,90h
count equ $-array ;数组的元素个数result db ? ;校验和
.code
.startup
INVOKE checksumd,count,offset array ;调用过程
mov result,al ;保存校验和
.exit 0
checksumd PROC c USES bx cx,
countp:word,arrayp:word
mov bx,arrayp ;BX←数组的偏移地址
mov cx,countp ;CX←数组的元素个数
xor al,al
sumd: add al,[bx] ;求和:AL←AL+DS:[BX]
inc bx
loop sumd
ret
checksumd endp
end
-----------------------------------------
;lt503.asm的列表文件(lt503.lst)
...
INVOKE checksumd,count,offset array
* mov ax,word ptr OFFSET array
* push ax
* mov ax,+000Ah
* push ax
* call checksumd
* add sp,04h
mov result,al
...
注释:* 指示该语句由汇编程序自动生成
------------------------------------------
checksumd PROC c USES bx cx,\
countp:word,arrayp:word
* push bp ;起始代码
* mov bp,sp
* push bx ;保护bx和cx
* push cx
mov bx,arrayp ;arrayp=[BP+6]
mov cx,countp ;countp=[BP+4]
...
ret
* pop cx ;结尾代码
* pop bx
* pop bp
* ret 0000h
checksumc endp
//[BP+4]:进入调试程序观察
宏结构程序设计
宏汇编
重复汇编
条件汇编
——统称宏结构
宏(Macro)是汇编语言的一个特点,它是与子程序类似又独具特色的另一种简化源程序的方法
宏——具有宏名的一段汇编语句序 ——宏定义时书写
宏指令——这段汇编语句序列的缩写——宏调用时书写
宏展开——宏指令处用这段宏代替的过程——宏汇编时实现
宏的参数功能强大,颇具特色
配合宏,还有宏操作符和有关伪指令
宏定义
ainbegin MACRO ;;定义名为mainbegin的宏,无参数
mov ax,@data ;;宏定义体
mov ds,ax
ENDM ;;宏定义结束
mainend MACRO retnum ;;带有形参retnum
mov al,retnum ;;宏定义中使用参数
mov ah,4ch
int 21h
ENDM
宏调用
start: mainbegin ;宏调用,建立DS内容
dispmsg string ;宏调用,显示字符串
mainend 0 ;宏调用,返回DOS
end start
宏调用的实质是在汇编过程中进行宏展开
宏展开的具体过程是:当汇编程序扫描源程序遇到已有定义的宏调用时,即用相应的宏定义体取代源程序的宏指令,同时用位置匹配的实参对形参进行取代
宏展开
tart: mainbegin ;宏指令
1 mov ax,@data ;宏展开
1 mov ds,ax
mainend 0 ;宏指令
1 mov al,0 ;宏展开
1 mov ah,4ch
1 int 21h
宏的参数
宏定义时,
可以无参数,例如5.4a的mainbegin
可以带有一个参数,例如5.4a的mainend
也可以具有多个参数;例如5.5a的shlext
参数可以是常数、变量、存储单元、指令(操作码)或它们的一部分,也可以是表达式;例如5.5b的shift和shrot
宏定义体可以是任何合法的汇编语句,既可以是硬指令序列,又可以是伪指令序列;例如5.6的dstring
例题
;宏定义
shlext macro shloprand,shlnum
push cx
mov cl,shlnum
shl shloprand,cl
pop cx
endm
;宏指令
shlext ax,6
;宏展开
1 push cx
1 mov cl,06
1 shl ax,cl
1 pop cx
;统一4条移位指令的宏指令
shift macro soprand,snum,sopcode
push cx
mov cl,snum
s&sopcode& soprand,cl
pop cx
endm
;统一移位和循环移位8条指令的宏指令
shrot macro sroprand,srnum,sropcode
push cx
mov cl,srnum
sropcode sroprand,cl
pop cx
endm
;宏定义
dstring macro string
db ’&string&’,0dh,0ah,’$’
endm
;宏调用
dstring < This is a example. >
dstring < 0 !< Number !< 10 >
;宏展开
1 db ’This is a example.’, 0dh,0ah,’$’
1 db ’0 < Number < 10’, 0dh,0ah, ’$’
宏操作符
;;——宏注释符,用于表示在宏定义中的注释。采用这个符号的注释,在宏展开时不出现
&——替换操作符,用于将参数与其他字符分开。如果参数紧接在其他字符之前或之后,或者参数出现在带引号的字符串中,就必须使用该伪操作符
< >——字符串传递操作符,用于括起字符串。在宏调用中,如果传递的字符串实参数含有逗号、空格等间隔符号,则必须用这对操作符,以保证字符串的完整
!——转义操作符,用于指示其后的一个字符作为一般字符,不含特殊意义
%——表达式操作符,用在宏调用中,表示将后跟的一个表达式的值作为实参,而不是将表达式本身作为参数
局部标号伪指令
LOCAL 标号列表
宏定义体采用了标号,应使用LOCAL加以说明
它必须是宏定义MACRO语句之后的第一条语句
宏定义删除伪指令
PURGE 宏名表
不需要某个宏定义时,可以把它删除
宏定义退出伪指令
EXITM
伪指令EXITM表示结束当前宏调用的展开