汇编程序基本概念 笔记

本文介绍了汇编语言程序的基本结构,包括源程序的段组成、语句格式,强调了程序起始点和终止点的设置,以及数据定义和变量定位。还详细讲解了可执行程序的结构,如.exe和.com格式的区别,并通过示例展示了数据类型的表示和变量的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、源程序格式

  • 由段组成
  • 包含若干code segment, data segment, extra segment(?), stack segment. Order is not concerned.
  • 需独立运行的程序必须有:一个代码段,指示程序执行的起始点(一个程序只有一个起始点)
  • 所有可执行性语句必须位于某一个代码段内;说明性语句可根据需要位于任一段内
  • 通常程序还需要一个堆栈段

二、语句格式

(1)executable code/执行性语句

  • 表达处理器指令(硬指令)/Machine code ——使CPU产生动作、并在程序执行时才处理的指令;与具体的processor有关,与assembler无关
  • 汇编后对应一条指令代码
  • 由处理器指令组成的代码序列——程序设计的主体
  • Label: Instruction Operand, Operand ;comment
  • Label(标号):硬指令位置(逻辑地址)和属性的标识符,跟冒号
  • Operand: immediate data, register, memory

(2) descriptive code/说明性语句

  • 表达伪指令 / Directive ——不产生CPU动作、在程序执行前由Assembler处理的说明性指令;与Processor无关、与assembler有关
  • 指示源程序如何汇编、变量怎样定义、过程怎么设置等
  • Name Directive Parameter,Parameter,... ;comment
  • Name(名字):伪指令位置(逻辑地址)和属性的标识符,无冒号
  • Parameter: constant, variable, expression

(3)标识符(Identifier)

(4)保留字(Reserved Word)/关键字——汇编程序已经利用的标识符

  • Instruction: MOV, ADD
  • Directive: DB, DW
  • Operator: OFFSET, PTR
  • Register: AX, CS
  • 预定义符号:@data

(5) MASM支持续行符“/"

(6)简化段定义格式

 

.model small ;定义程序的存储模式(小型模式)

.stack ;定义堆栈段(默认是1kb空间)

.data ;定义数据段

... ;数据定义

.coder ;定义代码段

start: mov ax,@data ;程序起始点

mov ds,ax ;设置DS指向用户定义的数据段

... ;程序代码

mov ax,4c00h

int 21h ;程序结束点,返回dos

... ;子程序代码

end start ;汇编结束,同时指明程序起始点start

 

关于程序的开始:

  • 在start后;
  • Linker会根据程序起始点正确地设置CS和IP值,根据程序大小和堆栈段大小设置SS和SP;
  • Linker没有设置DS和ES值。程序如果使用数据段或附加段,必须明确给DS或ES赋值;

关于程序终止和汇编结束:

  • 程序终止:mov ax,4c00h int 21h
  • 汇编结束:将源程序翻译成目标模块代码的过程结束:end start
  • 二者不同

 

(7)完整段定义格式

  • 利用segment和ends一对伪指令定义逻辑段
  • 同时配合assume伪指令,指明逻辑段是代码段、堆栈段、数据段、还是附加段
  • 优点:指明逻辑段的定位、组合、类别等属性

An example (identify which are states, which are directive)

 

Define a code segment at 0F800h

 

dumcod segment at 0f800h <Directive

org 9h <Directive

dumst label far <Directive

dumcod ends

;

;--------------Code Segment Here---------------;

;f8000-fffff for program <Directive

code_seg segment <Directive

assume cs:code_seg <Directive

;--------------Main Program here----------------;

start:

mov ax,data_seg <STATE

mov ds,ax ;initialize DS <STATE

assume ds:data_segment <Directive

mov ax,stack_seg <STATE

mov ss,ax ;initialize SS <STATE

assume ss:stack_seg <Directive

mov sp,top_of_stack ;initiaize SP<STATE

loop1: nop <STATE

jmp loop1 <STATE

;---------------Setup the Reset Vector----------;

org 07ff0h <Directive

jmp dumst <STATE

code_seg ends <STATE

end start <STATE

 

(8) 可执行程序的结构

两种可执行程序

.exe: 可以有多个代码段、数据段,程序长度可超过64kb;

.com: 只有一个逻辑段,程序长度不超过64kb.

 

三、数据

1. 常量

(1). 常数

(2). 字符串(DB)

其数值时每个字符对应的ASCII码值

'AB'=4142H

(3). 符号常量

EQU,'='

不占内存空间

(4). 数值表达式

2. 变量——可读写的内存单元——地址不变,数据可变

先定义,后使用

Define--DB, DW, DD

定义时,变量名有时可以缺省;

?表示未赋初值

DUP

符号地址:表示初值表首元素的逻辑地址

 

 

变量定义的实例:

DB

;data_seg

X db 'a',-5,?

   db 2 dup(100)

Y db ’ABC’

array db 2 dup(2,3,2 dup(4))

 

mov al, X

dec X+1

mov Y, al

 

DW

;data_seg

count dw 8000h,?,'AB'

maxint equ 64h

number dw maxint

array dw maxint dup(0)

 

DD

可以是有符号或无符号的32bits整数

也可以用来表达 16bit段地址和16bit的偏移地址的远指针

vardd DD 0,?,12345678h

farpoint DD 00400078h

 

 

练习:输出下列代码执行后的结果

;data_seg

bvar1 db 100,01100100b,64h,'d'

minint = 5

bvar2 db -1,minint,minint+5

db ?,2 dup(20h)

wvar1 dw 2010h, 4*4

wvar2 dw ?

dvar dd 12347777h,87651111h,?

abc db 'a','b','c',?

maxint equ 0ah

string db 'ABCDEFGHIJ'

crlfs db 13,10,'$'

array1 dw maxint dup(0)

array db 2 dup(2,3,2 dup(4))

 

;code_seg

mov dl,bvar1

dec bvar2+1

mov abc[3], dl

 

mov ax, word ptr dvar[0]

mov dx, word ptr dvar[2]

add ax, word ptr dvar[4]

adc dx, word ptr dvar[6]

mov word ptr dvar[8], ax

mov word ptr dvar[10], dx

mov cx, maxint

mov bx,0

again: add string[bx],3

inc bx

loop again

lea dx,abc

mov ah,9

int 21h

 

 

四、变量的定位


Assembler按照指令的先后顺序,一个接一个的分配存储空间;

按照段定义伪指令规定的边界定位属性,确定每个逻辑段的起始位置(包括偏移地址);

 

ORG 参数 ;控制数据或代码所在的偏移地址

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

e.g.:

1. org 100h ;从100h处安排数据或程序

2. org $+10 ;偏移地址加10,即跳过10个字节空间

 

$表示当前偏移地址值

 

五、名字和标号的属性

 

Name and Label

一经使用便具有两种属性

1. 什么属性?

2. 如何获取这些属性?

 

1. 逻辑地址属性——名字和标号对应存储单元的逻辑地址,含段地址和偏移地址;

类型属性——

变量名(name):byte/word/dword

标号(label)、段名(name)、子程序名(name):near/far

(near: 段内调用;far: 段间调用)

2. 使用操作符

地址操作符:

[]

$

: 段前缀,采用指定的段地址寄存器

OFFSET name/label

SEG name/label

类型操作符:

对名字或标号的类型属性进行设置

类型名(byte/word/dword/near/far) PTR name/label

 

对变量:lengthof(获知某变量名指向多少个数据项),sizeof(获知它占用多少字节空间)

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值