名称 proc
...; 实现逻辑功能的指令
(ret)
名称 endp
参考上面给出的汇编新结构,上面的一开始给出的汇编程序,可以写成下面这样:
ASSUME CS:CODE, DS:DATA, SS:STACK
STACK segment
db 16 dup(0)
STACK ends
code segment
start: mov ax,STACK
mov ss,ax
mov sp,16
mov ax,1000
call far ptr s ;调用子程序
mov ax,4c00h
int 21h
s: add ax,ax ;子程序开始
retf ;子程序结束
code ends
end start
public subp
assume cs:code
code segment
subp proc
s: add ax,ax
retf
subp endp
code ends
end
extrn subp:far
ASSUME CS:CODE, DS:DATA, SS:STACK
STACK segment
db 16 dup(0)
STACK ends
code segment
main proc
start: mov ax,STACK
mov ss,ax
mov sp,16
mov ax,1000
call far ptr subp ;调用子程序
mov ax,4c00h
int 21h
main endp
code ends
end start
masm p1;
masm p2;
link p1.obj+p2.obj;
每个指令详细用法,大家咨询查询资料,这里只列举出常用的一些汇编指令汇总
MOV,PUSH,POP,XCHG
IN,OUT,XLAT
LEA,LDS,LES
LEA指令中的SRC可以是一个数据标号,这样就直接把一个数据标号代表的地址赋给了REG寄存器
LDS和LES都是取出SRC代表内存空间开始四个字节值取出,前两个字节放REG,后两个字节放入DS或者ES中
标志寄存器传送指令
LAHF,SAHF,PUSHF,POPF
CBW:字节扩展到字
CWD: 字扩展到双字
ADD,ADC,INC
SUB,SBB,DEC,NEG,CMP
MUL,IMUL
DIV,IDIV
DAA,DAS,AAA,AAS,AAM,AAD
AND,OR,NOT,XOR,TEST
SHL,SHR,SAL,SAR,ROL,ROR,RCL,RCR
CLD: 设置方法为正向处理,di++
STD: 设置方法为负向处理,di--
assume cs:code,ds:data,es:extra
data segment ;定义数据段
...
data ends
;-------------------------------
extra segment ;定义附加段
...
extra ends
;--------------------------------
extra segment ;定义代码段
start:
mov ax,data
mov ds,ax ;段地址 段寄存器
...
code ends
end start
ASSUME 段寄存器:段名[,其他段声明]
段名 SEGMENT [定位类型] [组合类型] [使用类型] ['类别']
....
....
段名 ENDS
定位类型 align_type ---指明当前段的内存对齐方式,即该段再进行内存分配时的一个策略
PARA BYTE(字节对齐) WORD(字对齐) DWORD(双字对齐) PAGE(整页对齐)
组合类型 combine_type (多文件组织时,对存储空间和栈空间共享策略)
PRIVATE PUBLIC COMMON STACK AT exp
使用类型 use_type (16位或者32位)
USE16 USE32
类型 'class'
.MODEL 存储模式 [,其他选项]
存储模式:
- tiny
- small
- medium
- compact
- large
- huge
- flat
.code[name]
.data
.data?
.fardata[name]
.fardata?[name]
.const
.stack[size]
MASM 5.0/5.1不支持.startup和.exit
变量名 LABEL type
功能: 同一个变量(同一个空间)将具有不同的类型
BYTE_ARRAY LABEL BYTE
WORD_ARRAY DW 50 DUP(?)
ALPUA EQU 9
BETA EQU ALPUA+18
BB EQU [BP+8]
EMP=7
EMP=EMP+1
因为EQU和=都是针对常量进行操作,因此这些值在编译时就可以确定下来,不会等待运行时再去通过cpu来确定
mov ax,beta+emp
等同于,写成上面那样,方便管理,但是常量编译时可以确定,因此编译后其实长下面这样
mov ax,0023H
SEG1 SEGMENT
OGR 10
//默认分配在0地址处,但是上面有0RG,因此从10地址处进行分配
VAR1 DW 1234H
ORG 20
//从20地址处开始分配
VAR2 DW 5678H
//$为上面一条指令的地址
ORG $+8
//在$地址的基础上,加8,然后再对应的地址分配下面这个变量内存空间
VAR3 DW 1357H
ALIGN 4
ARRAY db 100 DUP(?)
A DB 'morning'
EVEN
B DW 2 DUP(?)
如果不明确指定,默认使用当前规定的基数,如果在数值末尾明确指定了基数,则不使用全局默认基数。
将一些基础的地址运算或者值计算,交给编译器在编译期间完成,等到编译完成后,形成的机器代码中,这些可以被计算出来的常量表达式都会被替换为对应的值
为真的时候,是-1,是因为把0FFFFH看做是有符号数
OFFSET,SEG,TYPE,LENGTH,SIZE
ARRAY DW 100 DUP(?)
TABLE DB 'ABCD'
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://cjdhy.blog.csdn.net/article/details/125716645
内容来源于网络,如有侵权,请联系作者删除!