《汇编语言程序设计》钱晓捷 第3章 汇编语言程序格式 学习笔记

目录

一、汇编语言程序的开发

1.语句格式

(1)标号和名字

(2)助记符

(3)操作数和参数

(4)注释

2.源程序框架

(1)简化段定义的源程序框架

(2)完整段定义的源程序框架

3.DOS系统功能调用

(1)字符输出(02号DOS功能)

(2)字符串输出(09号DOS功能)

(3)字符输入(01H号DOS功能)

(4)字符串输入(0AH号DOS功能)

(5)按键判断(0BH号DOS功能)

二、参数、变量、符号

1.数值型参数

2.变量定义伪指令

3.变量和标号的属性

(1)地址操作符

(2)类型操作符

三、程序段的定义和属性

1.DOS的程序结构

2.简化段定义的格式

(1)存储模型伪指令

(2)简化段定义伪指令

(3)程序开始伪指令

(4)程序终止伪指令

(5)汇编结束伪指令

(6)属性

3.完整段定义的格式

(1)完整段定义伪指令segment ends

(2)指定段寄存器伪指令assume

(3)段组伪指令group

(4)段顺序伪指令

四、复杂数据结构

1.结构

2.记录


一、汇编语言程序的开发

1.语句格式

执行性语句

标号: 处理器指令标记符 操作数,操作数

说明性语句

名字 伪指令标记符 参数,参数,...

(1)标号和名字

执行性语句中,标号表示处理器指令在主存中的逻辑地址,可有可无

说明性语句中,名字可以是变量名、段名、子程序名等,反映逻辑地址

标号和名字都是标识符,最多由31个字母、数字及规定的特殊符号(如$ ? @)组成,不能以数字开头

注:汇编语言对大小写不敏感

(2)助记符

助记符反映指令的功能,如MOV,DB

(3)操作数和参数

操作数可以是一个具体的常量,也可以是保存在寄存器的数据,还可以是一个保存在存储器中的变量。

参数可以是常量,变量名,表达式等,可以有多个,用“,”分隔

(4)注释

;后面的内容是注释,便于程序阅读

2.源程序框架

(1)简化段定义的源程序框架

以MASM 6.x版本的简化段定义为例

.model small  ;定义程序的存储模式(small表示小端存储)
.stack        ;定义堆栈段
.data         ;定义数据段
...
.code         ;定义代码段
.startup      ;程序起始点
...
.exit0        ;主程序代码
...           ;子程序代码

(2)完整段定义的源程序框架

stack segment stack
    ...
stack ends
data segment
    ...
data ends
code segment 'code'
    assume cs:code,ds:data,ss:stack
 start: mov ax,data
        mov ds,ax
        ...
        mov ax,4c00h
        int 21h
        ...
code ends     
     end start
        

3.DOS系统功能调用

DOS提供给程序员的编程资源是以中断调用方法使用的各种子程序

8086CPU支持256个中断,每个中断用中断编号区别,即中断0-255

DOS系统主要分配21h中断,用于程序员调用DOS操作系统功能。

一般方法:

(1)在ah寄存器中设置调用号

(2)在指定寄存器中设置入口参数

(3)int 21h

(4)分析调用执行情况

(1)字符输出(02号DOS功能)

例:

mov ah,02h    ;设置功能号
mov al,'?'    ;提供入口参数
int 21h       ;DOS功能调用:显示

按Ctrl+Break或Ctrl+C则退出

(2)字符串输出(09号DOS功能)

先将要显示的字符串保存在主存,设置入口参数DS:DX等于该字符串首地址,可以输出回车(0DH)和换行(0AH)字符产生回车和换行的作用

例:

string db 'Hello,every!',0dh,0ah,'$'
    mov ah,09h
    mov dx,offset string
    int 21h

(3)字符输入(01H号DOS功能)

AL保存出口参数,即输入字符的ASCII编码

例:判断按键是Y还是N

getkey: mov ah,1
        int 21h
        cmp al,'y'
        je teskey
        cmp al,'n'
        je nokey
        jne getkey

(4)字符串输入(0AH号DOS功能)

要事先在主存设置用于保存输入字符串的缓冲区,并严格按照以下要求:
1)缓冲区第1字节事先填入欲接收的字符个数(包括回车符)

2)第2字节将存放实际输入的字符个数(不包括回车符)

3)从第3字节开始存放输入的字符串

注:实际输入的字符数多余定义数时,多出的字符被丢掉

例:

buffer  db 81
        db 0
        db 81 dup (0)
        ...
        mov ah,0ah
        mov dx,seg buffer ;伪指令seg取得buffer的段地址
        mov ds,dx
        mov dx,offset buffer
        int 21h
        

(5)按键判断(0BH号DOS功能)

按键功能仅判断当前是否有按下的键,设置出口参数AL后退出

若AL=0,说明当前没有按键;如果AL=FFH,说明当前已经按键

getkey: mov ah,0bh
        int 21h
        or al,al   ;分析出口参数,AL=0?
        jz getkey  ;AL=0,没有按键,继续等待

二、参数、变量、符号

1.数值型参数

常数:

(1)十进制常数——以D/d结尾

(2)十六进制常数——以H/h结尾

(3)二进制常数——以B/b结尾

(4)八进制常数——以Q/q结尾

(5)字符串常数,如'd'==64H

(6)符号常数,利用标识符表达的一个数值

符号名 equ 数值表达式
符号名 equ <字符串>
符号名 = 数值表达式

例:

calldos equ <intt 21h>

注:EQU用于数值等价时不能重复定义符号名,但“=”允许有重复赋值

数值表达式

算术运算符:+,-,*,/,MOD

逻辑运算符:AND,OR,XOR(异或),NOT

移位运算符:SHL,SHR

关系运算符:EQ(相等),NE(不相等),GT(大于),LT(小于),GE(大于等于),LE(小于等于)

高低分离符:HIGH(高字节),LOW(低字节),HIGHWORD(高字),LOWWORD(低字)

2.变量定义伪指令

格式:

变量名 伪指令 初值表

变量名自定义,可没有,表示首元素的逻辑地址

伪指令有DB,DW,DD,DF,DQ,DT

DB为单字节,DW为单字,DD为双字,DF为3字(6字节),DQ为4字(8字节),DT为10字节

初值表是用","分割的参数,主要由数值参数,表达式或"?"(不确定),"DUP"(重复初值)组成

定位伪指令

(1)ORG参数

ORG将当前偏移地址指针指向参数表达的偏移地址

org 100h为从100h处安排数据或程序

org $+10  使偏移地址+10,即跳过10字节空间

(2)EVEN

EVEN使当前偏移地址指向偶数地址

(3)ALIGN n (n为2的乘方)

ALIGN 将当前偏移地址指针指向n的整数倍的地址

3.变量和标号的属性

标号和名字一经定义便具有以下属性:

(1)地址属性:标号和名字对应存储单元的逻辑地址

(2)类型属性:标号,子程序名的类型可以是NEAR/FAR

                           变量名的类型可以是BYTE,WORD,DWORD等

(1)地址操作符

offset 名字/标号  ;取得偏移地址
seg    名字/标号  ;取得段地址

(2)类型操作符

1)类型名 PTR 名字/标号

类型名可以为BYTE,WORD,DWORD,FWORD,QWORD,TBYTE

或是NEAR,FAR

还可以是由STRUCT,RECORD,UNION,TYPEDEF定义的类型

例:

mov al,bytr ptr w_var

2)THIS类型名

this创建使用当前地址,但是类型不同的操作数

b_var que this w_var ;b_var和w_var的地址相同,但是按字节访问
w_var dw 10 dup(0)

注:LABEL等同于EQU THIS

3)TYPE 名字/标号 (返回类型)

类似:

SIZEOF返回整个变量占用的字节数,LENGTH返回数据项数

故SIZEOF=LENGTH*TYPE

三、程序段的定义和属性

1.DOS的程序结构

2.简化段定义的格式

(1)存储模型伪指令

.MODEL语句,格式为:

.model存储模型[,语言模型][,操作系统模型][,堆栈选项]

存储模型有:
tiny
small
compact
medium
huge
large
flat

(2)简化段定义伪指令

1)栈段stack

.stack [大小]   ;段名为"stack"

2)数据段data

.data    ;段名为"_DATA",定义有初值变量
.data?   ;段名为"_BSS",定义无初值变量(在程序运行时才分配空间)

.const   ;段名为"CONST";建立只读的常量数据段

.FARDATA   ;建立有初值的远调用数据段
.FARDATA?  ;建立无初值的远调用数据段

3)代码段code

.code [段名]

若未给出段名,则为默认(TINY,SMALL,COMPACT,FLAT模型下默认为"_TEXT",MEDIUM,LARGE,HUGE模型下默认为"模块名_TEXT")

(3)程序开始伪指令

.STARTUP伪指令按照给定的CPU类型,根据.MODEL语句选择的存储模型、操作系统和对战模型,产生程序开始执行的代码,同时指定程序开始执行的起始点

(4)程序终止伪指令

.EXIT [返回数码]

通常返回数码为0表示无异常

.EXIT 0代码为:

mov ax,4c00h
int 21h

(5)汇编结束伪指令

end [标号]

标号用于指定程序开始执行点

(6)属性

3.完整段定义的格式

(1)完整段定义伪指令segment ends

段名 segment [定位][组合][段字]['类别']
    ...
段名 ends

;注:堆栈段要采用stack组合类型,代码段应具有'code'类别

1)段定位(Align)——指定逻辑段在主存储器中的边界

byte:段开始为下一个可用的字节地址,属性为1

word:段开始为下一个可用的偶数地址,属性为2

dword:段开始为下一个可用的4倍数地址,属性为4

para:段开始为下一个可用的节地址,属性为16

page:段开始为下一个可用的页地址,属性为256

简化段定义伪指令的代码和数据段默认采用WORD定位,堆栈段默认采用PARA定位

完整段定义伪指令的默认定位属性是PARA,偏移地址从0处开始

2)段组合(Combine)——指定多个逻辑段之间的关系

private(完整段定义默认):本段与其他段没有逻辑关系,不与其他段合并,每段都有自己的段地址

public(简化段定义默认):连接程序把本段与所有同名类型的其他段相邻地连接在一起,然后为所有这些段指定一个共同的段地址,即合成一个物理段

stack(堆栈段必须具有的组合):连接程序将所有stack段按照与public相同的方式进行合并

common:连接程序把所有同名同类型逻辑段制定统一地址,后面的同名同类型将覆盖前面的段,主要用于共享数据

3)段字(Use)——为支持32位段而设置的属性

16位x86CPU默认16位段,即USE16

32位x86CPU默认32位段,即USE32,但可以使用USE16制定标准的16位段

4)类别(Class)——连接程序组织段时,所有同类别段相邻分配

类名位于单引号

大部分MASM用'code','data','stack'

(2)指定段寄存器伪指令assume

assume 段寄存器名:段名[,段寄存器名:段名]

段名参数可以是:

1.以段定义位置了设置的段名

2.以GROUP伪指令设置的组名

3.保留字NOTHING(表示取消指定的段寄存器与段名的关系)

4.用SEG操作符返回的段地址

汇编程序会根据数据所在的逻辑段,在需要时自动插入段超越前缀

!注:assume不为段寄存器设定初值

(3)段组伪指令group

组名 gruop 段名[,段名...]

段名还可以有 "SEG 变量名/标号名" 形式

段组内各段统一为一个段地址,各段定义的变量和标号的偏移地址相对于段组基地址计算

(4)段顺序伪指令

段在主存中的实际顺序可以设置:

.seg             按照源程序的隔断排序

.dosseg       按照其他微软的程序设计语言使用的标准DOS规定

.alpha          按照段名的字母顺序

完整段定义格式默认.seg,简化段定义默认.dosseg

四、复杂数据结构

1.结构

结构类型定义:

结构名 struct

           ...

结构名 ends

结构变量定义:

变量名 结构名 <字段初值表>

引用:

结构变量名.结构字段名

例:

student struct 
        sid dw ?
        sname db 'abcdefgh'
        math db 0
        english db 0
student ends

stu1 student<1,'zhang',85,90>

mov stu1.math,95

2.记录

(1)记录类型说明

记录名 record 位段[,位段……]

 

位段格式:

位段名:位数[=表达式]

记录长度小于8位时,汇编成1字节

记录长度为8-16位时,汇编成1个字

位段从地位对齐,不用的位为0

person record year:4,sex:1=0,marriage:1=1

(2)记录变量定义

记录变量名 记录名 <段初值表>

zhang person <1000b,1,0>  ;值为00100010b=22h

(3)记录变量的引用和记录操作符

变量名:直接引用变量

记录位段名:该位段移位到最低位D0的移位次数

width 记录名/记录位段名:返回记录或记录位段所占的位数

mask 记录位段名:返回记录或记录位段所占的次数

mov al,zhang         ;al<--22h
mov bl,year          ;bl<--2
mov cl,width person  ;cl<--6
mov cl mask sex      ;dl<--00000010b=02h

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云霄星乖乖的果冻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值