表达式
表达式中的求值是在程序链接时完成的,所以表达式中的各值必须是在汇编或链接期就能确定,也就是说不能将寄存器或者变量运用于表达式。
算术表达式
逻辑运算
逻辑运算即位运算,逻辑运算符与对应的指令助记符单词是相同的,当它们出现在操作码部分时是指令,出现在操作数时是逻辑运算符。 ```matlab mov ax,5566h and 6655h mov ax,7788h or 8877h mov ax,not 5566h mov ax,5566h xor 7788h
<a name="8E1jy"></a>
### 标号
- @@是匿名标号
- @b向上查找最近的@@,b是back
- @f向下查找最近的@@,f是front
```matlab
@@:
mov ax,5566h and 6655
@@:
mov ax,7788h or 8877h
jmp @b ;跳转到第三行
jmp @f ;跳转到第8行
@@:
mov ax,not 5566h
@@:
mov ax,5566h xor 7788h
调整偏移量指令ORG
- 格式ORG偏移值
- 此指令后的下一个变量或指令从偏移开始存放 ```matlab data_seg segment g_buf dw 10h dup(0) org 20h g_w dw 65h ;段偏移20h开始存放 org 4 g_20 dw 655h ;会与buff的第四个字节开始的数据重复 data_seg ends
CODE segment START: org 100h mov ax,5566h and 6655h ;此指令从 代码段偏移100h开始存放
mov ax,4c00h int 21h CODE ends end START
<a name="BcTkr"></a>
### 当前地址伪指令
- $伪指令代表当前指令或变量的地址
- 可用于
- 可与**ORG**配合使用
```matlab
data_seg segment
g_buf dw 10h dup(0)
g_len dw $ - offset g_buf; 获取上面g_buf的长度
org $ + 10h ;下一个遍历从当前地址+10h的偏移开始存放
g_w dw 65h
data_seg ends
CODE segment
START:
org 100h
mov ax,5566h and 6655h ;此指令从 代码段偏移100h开始存放
mov ax,$ ;获取本条指令的地址
mov ax,$+4;获取本条指令的地址+4
mov ax,4c00h
int 21h
CODE ends
end START
- 花指令 ```matlab ;======================================;======================================data segment data segment db 1 g_sz db “hello world”,0 g_wLen dw $ - offset g_sz ;存放g_sz的长度 g_sz2 db “ell”,0 org $+10h g_w dw 5566h g_w2 dw 7788h data ends ;======================================;======================================stack segment stack segment stack dw 20h dup(?) top label word stack ends
;======================================;======================================code segment code segment assume ds:data,cs:code,ss:stack start: ;=========================================INIT mov ax,data mov ds,ax
mov ax,stack
mov ss,ax
lea sp,top
;=========================================code todo LABEL_THIS: mov ax,offset LABEL_THIS mov ax,$
;===========花指令
jmp $+3
db 0e9h
mov ax,67 ;
;===========
;=========================================code ends
ENDCODE:;程序退出
mov ah,4ch
int 21h
;====================================================
code ends
end start
<a name="aPRCK"></a>
### 结构体
```matlab
结构体名 struc
;这里定义结构体成员
结构体名 ends
局部变量和全局变量使用示例:
;======================================;======================================stack segment
stack segment stack
dw 20h dup(?)
top label word
stack ends
;======================================;======================================
Student struc
m_id dw ?
m_sz db 256 dup(?)
Student ends
data_seg segment
g_stu Student <56,"hello world...">
data_seg ends
code_seg segment
Func PROC far c uses bx cx si di src:word,substr00:word
local @stu:Student
mov @stu.m_id,78
lea bx,@stu.m_sz
;寄存器使用
assume bx:ptr Student ;要明确高数它这个是哪个结构体的指针
lea bx,@stu
mov [bx].m_id,99
assume bx:onthing ;用完之后nothing一下释放
ret
Func ENDP
code_seg ends
;======================================;======================================code segment
code segment
assume ds:data_seg,cs:code,ss:stack
start:
;=========================================INIT
mov ax,data_seg
mov ds,ax
mov ax,stack
mov ss,ax
lea sp,top
;=========================================code todo
mov g_stu.m_id,56
lea bx,g_stu.m_sz
invoke Func,bx,cx
;=========================================code ends
ENDCODE:;程序退出
mov ah,4ch
int 21h
;====================================================
code ends
end start
宏
equ语句
- 不可以重命名
- 可用于常量和表达式
- 可用于字符串
- 可用于指令名,给指令取别名
- 可用于类型,给类型取别名
可用于操作数
COUNT equ 100h ;后跟数值
SZHELLO equ "hello world"
MOVE equ mov ;后跟助记符
MYWORD equ dw ;后跟类型
BX_CONE eque byte ptr [bx];后跟表达式
示例2:
MAXBYTE equ 255
VERSION equ "5.261"
MOVE equ mov
GETBX equ byte ptr [bx]
WORDBYPE equ dw
;定义后,其下面就可以直接使用它们
=语句
可以被修改
只能用于常数
COUNT2 = 100h ;后跟数值
COUNT2 = 200h;可以再次赋值
mov ax,COUNT2
;==================
;函数内
@val1 = -2
@val2 = -4
test00 equ 100
;下面两条使用局部变量看起来更舒服
mov ax,[bp+@val1]
mov ax,[bp+@val2]
mov ax,test00
macro语句
格式
宏名 macro [参数1][参数2]...
宏体
endm
宏会在使用的地方展开
- 宏可以带参数
- 字符串拼接使用&
常用的一些用法示例: ```matlab ExitProcess macro mov ax,4c00h int 21h endm movm macro arg1,arg2 push arg2 pop arg1 endmmovm marco op1,op2
push op2
pop op1
endm
shift macro n,reg,d
mov cl,n
ro&d reg,cl
endm
shift4 MACRO reg,der mov cl,4 ro&der reg,cl ENDM ;======================================;======================================stack segment stack segment stack dw 20h dup(?) top label word stack ends ;======================================;======================================
data_seg segment g_dw1 dw 5566h g_dw2 dw 7788h data_seg ends
code_seg segment Func PROC far c uses bx cx si di src:word,substr00:word
ret
Func ENDP code_seg ends ;======================================;======================================code segment code segment assume ds:data_seg,cs:code,ss:stack start: ;=========================================INIT mov ax,data_seg mov ds,ax
mov ax,stack
mov ss,ax
lea sp,top
;=========================================code todo movm g_dw1,g_dw2
shift4 ax,r
shift4 bx,l
;=========================================code ends ENDCODE:;程序退出 ExitProcess ;==================================================== code ends end start
更多宏语法可以查找老师之前给的资料->汇编中文手册
![image.png](https://cdn.nlark.com/yuque/0/2021/png/12923347/1633014135913-bf41b4c5-3a49-4afe-b090-3bfd80229472.png#align=left&display=inline&height=476&margin=%5Bobject%20Object%5D&name=image.png&originHeight=476&originWidth=634&size=427752&status=done&style=none&width=634)
<a name="hII9n"></a>
## 多文件编译
源文件
- 源文件后缀名为asm
- 每个源文件末尾需要有end
头文件
- 汇编头文件后缀名为inc
- 头文件包含include xxx.inc
- 头文件防重复包含
**示例:**<br />Test.asm
```matlab
include 2.inc
ExitProcess macro
mov ax,4c00h
int 21h
endm
movm macro arg1,arg2
push arg2
pop arg1
endm
shift4 MACRO reg,der
mov cl,4
ro&der reg,cl
ENDM
;======================================;======================================stack segment
stack segment stack
dw 1024h dup(?)
top label word
stack ends
;======================================;======================================
data_seg segment
g_dw1 dw 5566h
g_dw2 dw 7788h
data_seg ends
;======================================;======================================code segment
code segment
assume ds:data_seg,cs:code,ss:stack
start:
;=========================================INIT
mov ax,data_seg
mov ds,ax
mov ax,stack
mov ss,ax
lea sp,top
;=========================================code todo
movm g_dw1,g_dw2
invoke Func,bx,cx
mov ax,g_w2
shift4 ax,r
shift4 bx,l
;=========================================code ends
ENDCODE:;程序退出
ExitProcess
;====================================================
code ends
end start
2.inc
ifndef MY_2_INC_XXXXX ;防止重复包含
MY_2_INC_XXXXX equ 0 ;防止重复包含
Func proto far c src:word,substr00:word
extern g_w2:word
endif ;防止重复包含
2.asm
public g_w2 ;去掉g_w2的默认static属性
data segment
g_w2 dw 9999h
data ends
code segment
Func PROC far c uses bx cx si di src:word,substr00:word
.if ax > 0
.endif
ret
Func ENDP
code ends
end
编译连接方法:
- ml *.asm
- ml test.asm 2.asm
- ml /c test.asm 2.asm link test.asm 2.asm
下面是test调用2的函数和使用2的全局变量
汇编中文手册:用伪指令实现的分支结构