?汇编语言的基本语法
?常量
数值常量,01000101B,32,0F1D4H
符号常量(用 EQU或 =定义)
?变量
内存单元的名字,由 DB/DW/DD/DQ/DT定义
?标号
指令存放单元的符号地址,是转移 /调用 /循环
指令的操作数
?指令语句
执行性的语句,汇编时汇编程序将其转换成
机器目标代码
标号,指令助记符 操作数 ;注释
?伪指令语句
说明性的语句,为汇编程序提供进行汇编所
需要的有关信息,如定义符号、分配存储单
元等,不生成目标代码
名字 伪操作命令 操作数 ;注释
实模式汇编语言源程序的结构 —— 完整的段定义
DATA SEGMENT
…...
DATA ENDS
STACK SEGMENT STACK
…...
STACK ENDS
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START,……
CODE ENDS
END START
?段定义伪指令
段名 SEGMENT [属性 ]
……
段名 ENDS
DATA SEGMENT PARA ‘DATE’
段对齐属性
BYTE/WORD/DWORD/PARA/PAGE
段类属性
‘ CODE’/’DATA’/’STACK’/’EXTRA’
?段寄存器定义伪指令
ASSUME 段寄存器,段名 [,段寄存器,段名,...]
?ASSUME语句习惯上作为代码段的第一条指令
?ASSUME语句是非执行性的伪指令,段寄存器
的初值必须在程序中用指令设置。
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
MOV AX,DSEG
MOV DS,AX
…...
?对 CS的赋值由操作系统装入 EXE文件时自动
完成
?分支结构
程序段 Y 程序段 N
条件
JZ LY
LY,……
…...
LN,…...
后继程序 L0,…...
JMP L0
TEST AX,1
Y N
IF … THEN … ELSE
程序段 N
后继程序段 Y
条件
JZ LY
LY,……
…...
…...
TEST AX,1
?分支结构
N Y
IF … THEN
LN:
?循环结构
DO-UNTIL
3? ê? ?ˉ 2? ·?
?- ?·ì?
DT ?? 2? ·?
ì? ?t
3? ê? ?ˉ 2? ·?
?- ?·ì?
DT ?? 2? ·?
ì? ?t
oó ?ì 3ì Dò
WHILE-DO
?循环控制:
计数控制 LOOP/...
条件控制 JZ/...
例:计算 1+2+3+…+100
MOV AX,0
MOV BX,0
MOV CX,64H
INC BX
ADD AX,BX
LOOP SUM
SUM:
例:从 1开始累加,直到和大于 10000为止,统
计被累加的整数个数
MOV AX,0
MOV BX,0
MOV CX,0H
INC BX
ADD AX,BX
INC CX
CMP AX,2710H
JLE SUM
SUM:
汇编语言源程序的结构 —— 简化的段定义
MASM提供了简化的段定义伪指令,使用指
定的内存模式编程。
.586
.MODEL SMALL
.DATA
.STACK 100
.CODE
.STARTUP
.EXIT
END; 选择指令系统; 内存模式说明; 定义数据段; 定义堆栈段; 定义代码段; 指示程序开始,初始化 DS,SS寄存器; 结束程序,返回操作系统
?内存模式
?TINY 程序和数据在 64K字节段内
?SMALL 独立的代码段和独立的数据段
?MEDIUM 单个数据段,多个代码段
?COMPACT 单个代码段,多个数据段
?LARGE 多个代码段,多个数据段
子程序设计
?过程定义
过程名 PROC [类型 ]
…… ; 指令序列
RET ;过程 返回指令
过程名 ENDP
类型:
NEAR—— 与主程序在同一个段
FAR —— 可以与主程序不在同一个段
子程序设计
?过程调用
近程调用
CALL 过程名
?将当前 IP寄存器内容进栈(保存 CALL下一
条指令的偏移地址)
?将被调用过程的偏移地址送 IP寄存器,控制
程序转移到该过程
DATA SEGMENT
MESSAGE DB "Hello world!",0DH,0AH,"$"
DATA ENDS
SSEG SEGMENT STACK
DB 100 DUP(?)
SSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DATA,SS:SSEG
START:
MOV AX,DATA
MOV DS,AX
CALL DISPLAY
MOV AH,4CH
INT 21H
DISPLAY PROC
MOV DX,OFFSET MESSAGE
MOV AX,SEG MESSAGE
MOV DS,AX
MOV AH,9
INT 21H
RET
DISPLAY ENDP
CSEG ENDS
END START
远程调用
CALL FAR PTR 过程名
?将当前 CS寄存器内容进栈(保存 CALL下一
条指令的段地址)
?将当前 IP寄存器内容进栈(保存 CALL下一
条指令的偏移地址)
?将被调用过程的偏移地址送 IP寄存器,段地
址送 CS寄存器,控制程序转移到该过程
?过程调用
DATA SEGMENT
MESSAGE DB "Hello world!",0DH,0AH,"$"
DATA ENDS
SSEG SEGMENT STACK
DB 100 DUP(?)
SSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DATA,SS:SSEG
START:
MOV AX,DATA
MOV DS,AX
CALL FAR PTR DISPLAY
MOV AH,4CH
INT 21H
DISPLAY PROC FAR
MOV DX,OFFSET MESSAGE
MOV AX,SEG MESSAGE
MOV DS,AX
MOV AH,9
INT 21H
RET
DISPLAY ENDP
CSEG ENDS
END START
子程序设计
?返回指令
REP
REP n
实现返回功能,并调整 SP,即
SP+n SP
子程序设计
?寄存器的保存与恢复
SUB PROG
PUSH BX
MOV BX,AX
SHL BX,1
ADD AX,BX
POP BX
RET
SUB ENDP
子程序设计 —— 参数传递
三种方式:通过寄存器 /通过内存 /通过堆栈
?通过寄存器
在调用过程前将参数置入寄存器
.MODEL SMALL
.STACK
.DATA
MESSAGE DB "The Sum is "
SUMRST DB?,"$"
.CODE
.STARTUP
MOV AL,1
MOV BL,2
CALL SUM
MOV AH,9
MOV DX,OFFSET MESSAGE
INT 21H
.EXIT
SUM PROC
ADD AL,BL
OR AL,30H
MOV SUMRST,AL
RET
SUM ENDP
END
子程序设计 —— 参数传递
?通过内存
.DATA
MESSAGE DB "The Sum is "
SUMRST DB?,"$"
D1 DB?
D2 DB?
.CODE
.STARTUP
MOV D1,1
MOV D2,2
CALL SUM
MOV AH,9
MOV DX,OFFSET MESSAGE
INT 21H
.EXIT
SUM PROC
MOV AL,D1
ADD AL,D2
OR AL,30H
MOV SUMRST,AL
RET
SUM ENDP
END
子程序设计 —— 参数传递
?通过堆栈 —— 功能最强 /最灵活 /最复杂
MOV AL,1
MOV BL,2
MOV AH,0
MOV BH,0
PUSH AX
PUSH BX
CALL SUM
POP BX
POP AX
?通过堆栈
SUM PROC
PUSH BP
MOV BP,SP
MOV AX,[BP+6]
MOV BX,[BP+4]
ADD Al,BL
OR AL,30H
MOV SUMRST,AL
POP BP
RET
SUM ENDP
宏指令与宏调用
?宏指令定义语句
宏指令名 MACRO
宏体
ENDM
SAVEREGS MACRO
PUSH AX
PUSH BX
PUSH CX
PUSH DX
ENDM
?LOCAL伪指令
使用宏时,可能会导致变量、标号重定义
的问题,使用 LOCAL伪指令可以解决这一
问题
LOCAL 变量 /标号列表
SOMEMACRO MACRO
LOCAL L1,N2
……
L1,…….
…….
L2,…….
ENDM
?带参数的宏指令
宏指令名 MACRO 参数 1,参数 2,…,参数 n
宏体
ENDM
SUM MACRO NUM1,NUM2,RESULT
PUSH AX
MOV AX,NUM1
ADD AX,NUM2
MOV RESULT,AX
POP AX
ENDM
?宏调用
宏指令名 参数列表
?宏指令与子程序的区别
?子程序调用由微处理器完成
宏指令调用在汇编过程中由汇编程序完成
?子程序调用可以减小目标程序的大小
宏指令调用不能
DATA SEGMENT
MESSAGE DB "Hello world!",0DH,0AH,"$"
DATA ENDS
SSEG SEGMENT STACK
DB 100 DUP(?)
SSEG ENDS
DISPLAY MACRO MSG
MOV DX,OFFSET MSG
MOV AH,9
INT 21H
ENDM
CSEG SEGMENT
ASSUME CS:CSEG,DS:DATA,SS:SSEG
START:
MOV AX,DATA
MOV DS,AX
DISPLAY MESSAGE
MOV AH,4CH
INT 21H
CSEG ENDS
END START
模块化程序设计
模块:能够独立汇编的若干逻辑段的汇编语
言源程序
主模块:只能有一个,以,END 启动指令标
号”作为源程序的结束语句
子模块:可以有多个,以,END”作为源程序
的结束语句
模块化程序设计
?PUBLIC伪指令
PUBLIC 符号列表
用在被调用模块,统治连接程序列出的变
量 /过程 /标号能够被其他模块引用
模块化程序设计
?EXTERN伪指令
PUBLIC 符号名:类型,符号名:类型
类型,BYTE/WORD/…/NEAR/FAR
用在调用模块,统治汇编程序所列出的变
量 /过程 /标号定义在其他模块中
模块化程序设计
?INCLUDE伪指令
INCLUDE 文件名
功能与 C/C++中的 include语句相同
不同模块中的代码段 /数据段可以组合成统
一的代码段 /数据段,也可以不组合
如要组合:
1.各模块中选用相同的段名
2.段定义语句中使用 PUBLIC参数
模块化程序设计
如果各模块的代码段组合成一个代码段,
那么模块间的转移为段内转移,子程序调
用为近程调用
4.7 与高级语言的接口
C对汇编语言的调用
?命名约定
C语言程序编译时自动在函数名、过程名前加
上下划线,_”,而调用时直接使用过程名。
C程序中直接调用 sum(3,5)
则汇编语言的过程名应为 _sum
C对汇编语言的调用
?调用约定
C程序中对要调用的外部过程用 extern关键
字进行说明
extern int sum(int,int);
C对汇编语言的调用
?参数传递约定
C程序向汇编程序传送参数通过堆栈进行,
采用 C调用规则进行参数传递:
参数压栈顺序与参数表中出现的顺序相反,
第一个参数最后压栈
通过 AL,AX或 DX:AX寄存器返回结果
C对汇编语言的调用
?参数传递约定
高地址
低地址
堆栈
生长
方向
BP保护
返回地址
参数 1
参数 2
参数 3
BP
BP+2
BP+4
BP+6
PUBLIC _sum
_sum PROC NEAR
PUSH BP
MOV BP,SP
MOV AX,[BP+4]
……
POP BP
RET
_sum ENDP
.MODEL SMALL
.CODE
PUBLIC _SUM
_SUM PROC
PUSH BP
MOV BP,SP
MOV AX,[BP+4]
MOV BX,[BP+6]
ADD AX,BX
POP BP
RET
_SUM ENDP
END
#include <stdio.h>
extern int sum(int a,int b);
void main()
{
printf("The sum is %d \n",sum(5,3));
}
C对汇编语言的调用