汇编语言(二) - 数据表示和寻址

简介
  • 理解计算机的数据表达
  • 熟悉汇编语言的常量表达
  • 掌握汇编语言的变量定义和属性
  • 掌握处理器指令的数据寻址方式

1.数据表示

数据(Data):计算机处理的对象

  • 指令操作的对象:操作数(Oprand)
  • 用二进制的0和1组合表示
  • 任何进入计算机的信息都要转换成0和1的数码

MASM的内部数据类型

  • 基本特征:以数据位(bit)数目作为量度
    8bit、16bit、32bit、48bit、64bit、80bit
  • 其他特征
    符号、指针、浮点
1.1 数制

在这里插入图片描述
1.二进制
注意:加减法会出现进位或借位,乘积和被除数是双倍长的数据,除法有商和余数两个部分。
后缀字母B(或小写b)表示二进制形式表达的数据。

二进制运算规则
加法运算减法运算乘法运算
1 + 0 = 11 - 0 = 11 * 0 = 0
1 + 1 = 0 (进位1)1 - 1 = 01 * 1 = 1
0 + 0 = 00 - 0 = 00 * 0 = 0
0 + 1 = 10 - 1 = 1 (借位1)0 * 1 = 0

2.逻辑运算
二进制数的逻辑运算就是按位(各位独立)逻辑运算的过程。

逻辑运算规则
逻辑与运算逻辑或运算逻辑非运算逻辑异或运算
1 & 0 = 01 | 0 = 1~ 0 = 11 ^ 0 = 1
1 & 1 = 11 | 1 = 11 ^ 1 = 0
0 & 0 = 00 | 0 = 0~ · = 00 ^ 0 = 0
0 & 1 = 00 | 1 = 10 ^ 1 = 1

更详细的逻辑操作: https://blog.csdn.net/weixin_42216574/article/details/82885102

3.十六进制
常使用十六进制表达地址、数据、指令代码等,后缀H(或者小写h)表示十六进制形式表达的数据。
23D9H + 94BEH = B897H, A59FH - 62B8H = 42E7H
4.数制之间的转换

  • 二进制数、十六进制数转换为十进制数按权展开。
  • 十进制数的整数部分转换为二进制数和十六进制数可用除法,即把要转换的十进制数的整数部分不断除以二进制数和十六进制数的技术2或16,并记下余数,直到商为0为止,再由最后一个余数起逆向取各个余数,则为该十进制数整数部分转换成的二进制数或十六进制数。
  • 十进制数的小数部分转换为二进制数和十六进制数则可分别乘以各自的基数,记录整数部分,直到小数部分为零为止。
    0.8125 = 0.1101B, 0.8125 = 0.DH
    小数部分的转换可能会发生总是无法乘到为0的情况,这时可选取一定位数(精度),当然也势必长生无法避免的转换误差。
  • 二进制数和十六进制数之间的对应关系:
    以小数点为基准,整数从右往左(从低位到高位)、小数从左到右(从高位到低位)每四个二进制位对应一个十六进制位。
    在这里插入图片描述
1.2 数值的编码

编码

  • 用文字、符号或者数码来表示某种信息(数值、语言、操作指令、状态等)的过程

二进制编码:组合0和1数码
机器数:计算机用0和1数码组合表达的数值
真值:现实中真实的数值
数值的两种编码方式

  • 定点格式
  • 浮点格式

1.定点整数
固定小数点的位置表达数值

  • 整数:固定在机器数的最右侧
  • 小数:固定在机器数的最左侧

在这里插入图片描述
无符号整数(无符号数)

  • 只表达0和正整数的定点整数
  • N位无符号整数表达范围0~2^N-1

有符号整数(有符号数、带符号数)

  • 表达负整数、0和正整数的定点整数
  • 最高位(符号位)表达数值正负
  • 0–正数,1–负数
    在这里插入图片描述

2.补码
有符号整数有很多种表达形式,计算机中默认采用补码。因为采用补码,减法运算可以变换成加法运算,所以硬件电路只需设计加法器。
有符号整数,计算机默认采用补码表示

  • 正数补码:直接表示数值大小(同无符号数)
  • 负数补码:将对应正数补码取反加1

8位二进制补码的数值范围:-128~+127
16位二进制补码的数值范围:-2^ 15~+2^15 -1
32位二进制补码的数值范围:-2^ 31~+2^31 -1
N位二进制补码的数值范围:-2^ N-1~+2^N-1 -1
负数求补
负数真值“取反加1”得机器数补码
负数补码“取反加1”得到负数真值

  • 补码:11100000B
  • 真值:-([11100000]求反+1)=-(00011111+1)
    =-00100000=-2^5=-32

负数求补运算,等效于用带进位的0作减法

  • 真值:-8,补码:[-8]补码 =00H - 08H = F8H
  • 补码:11111000,真值:-(00H - F8H) = -08H = -8

在这里插入图片描述
3.补码运算
利用无符号数加法结合补码表达可以实现

  • 有符号数加法
  • 有符号数减法
  • 无符号数加法
  • 无符号数减法

无符号数加减运算,需要利用进位或错位
有符号数加减运算,注意避免出现溢出
在这里插入图片描述

1.3 字符的编码

字符的二进制编码

  • 计算机中用若干位的二进制码组合表示各种字符

基于计算机的基本存储单位是字节(byte),以8个bit为单位表达字符

1.BCD码

二进制binary编码的十进制数decimal

  • 一个十进制数位用4位二进制编码来表示
  • 8421 BCD码:4位二进制编码的低10个编码表示0~9
  • 压缩BCD码:一个字节表达两位BCD码
  • 非压缩BCD码:一个字节表达一位BCD码(低4位表达数值,高4位常设置为0)

BCD码特点:直观

  • BCD码: 0100 1001 0111 1000.0001 0100 1001
  • 十进制真值: 4 9 7 8.

(3456)10=(0011010001010110)压缩BCD
(3456)10=(00000011000001000000010100000110)非压缩BCD
BCD码便于输入输出,表达数值准确

2.ASCII(美国标准信息交换码)
标准ASCII码用7位二进制编码,有128个

  • 不可显示的控制字符:前32个和最后一个
    • 回车CR:0DH 换行LF:0AH 响铃BEL:07H
  • 可显示和打印的字符:20H及以后的95个编码
    • 数码0~9:30H~39H
    • 大写字母A~Z:41H~5AH
    • 小写字母a~z:61H~7AH
    • 空格:20H

扩展ASCII码:最高D7位为1,表达制表符号

ASCII(美国标准交换标准码)字符表(7位表) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200519092925978.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU1Njk2OA==,size_16,color_FFFFFF,t_70#pic_center) **3.Unicode(统一码)** 8位ASCII码表达英文字符 16位国标码表达汉字字符
  • 汉字机内码:国标码在计算机中使用的编码
    国际信息交换码Unicode
  • 16位编码,兼容ASCII
  • 对世界上所有语言的大多数字符进行编码
  • 提供扩展能力
  • http://www.unicode.org/

Unicode给每个字符提供了一个唯一的数字,不论是什么平台,不论是什么程序,不论是什么语言

2. 常量表达

常量具有确定数值
1. 常数

各种进制的常数
进制数组组成举例
十进制由 0 ~ 9 数字组成,以字母D或d结尾(默认情况下可以省略)100, 255D
十六进制由 0 ~ 9 , A ~ F 组成,以字母H或h结尾;以字母A~F开头前面要用0表达,以避免与标识符混淆64H, 0FFH, 0B800H
二进制由 0 或 1 两个数字组成,以字母B或b结尾01101100B

2. 字符和字符串
字符常量

  • 以单引号或双引号括起来的单个字符
  • 例如:‘A’ “d”

字符串常量

  • 以单引号或双引号括起来的一串字符
  • 例如:
    • ‘ABC’
    • ‘4096’
    • “Goodnight, Gracie”
  • 引号可以嵌套:
    • “This isn’t a test”
    • ‘Say “Goodnight,” Gracie’
    3. 符号常量
    建立标识符与整数表达式或文本之间的联系
    类似于C/C++的 #define PI 3.14159
    格式
  • 符号名 EQU 数值表达式 ; PI EQU 3.14159
  • 符号名 EQU <字符串> ; CRLF EQU <13,10>
  • 符号名 = 数值表达式 ; COUNT = COUNT +64H

限制

  • EQU用于数值时不能重复定义符号名
  • =允许重复赋值

符号常量与变量的区别:

  • 不占用实际的存储空间
  • 仅在编译期间使用,不能在运行期改变

4. 数值表达式
用算数运算符与整数量连接组成的算式,运算结果为整数
算术运算符:

  • 一元运算符+(正),-(负)
  • 二元运算符+(加), -(减), *(乘), /(除),MOD(取余)
  • 优先级运算符 ()

地址表达式表达存储单元(只能使用+、-)

  • 地址 + 常量
  • 地址 - 常量

由于表达式是在程序运行前的汇编阶段计算,所以组成表达式的各部分必须在汇编时就确定。

3. 变量应用

变量类型-内部数据类型
在这里插入图片描述

3 .1 变量定义

作用: 申请存储空间,初始化存储单元
1.变量定义伪指令
汇编格式wei:

变量名	变量定义伪指令	初值表

变量名:标识符,第一个元素的逻辑地址
类型定义伪指令

  • BYTE、WORD、DWORD、FWORD、QWORD、TBYTE
  • 传统表示:DB,DW,DD,DF,DQ,DT

初值表:用“,”逗号分隔的参数

  • 各种形式的常量
  • ?表示不确定值(未赋初值)
  • 复制操作符DUP
变量定义伪指令
助记符变量类型变量定义功能
BYTE字节分配一个或多个字节单元;每个数据是字节量,也可以是字符串常量;
字节量表示8位无符号数或有符号数、字符的ASCII码值
WORD分配一个或多个字单元;每个数据是字量,16位数据
字量表示16位无符号数或有符号数、16位段选择器、16位偏移地址
DWORD双字分配一个或多个双字单元;每个数据是双字字量,32位数据
双字量表示32位无符号数或有符号数、32位段选择器、32位偏移地址
FWORD三个字分配一个或多个6字节单元
6字节量常表示含16位段段选择器和32位偏移地址的48位指针地址
QWORD四个字分配一个或多个八字节单元
八字节量表示64位数据
TBYTE十个字分配一个或多个10字节单元,表示BCD码、10字节数据(用于浮点运算)

2.字节量数据
分配1~n个字节的存储空间
初始值:8位整数表达式或字符常量
表达:

  • 无符号整数0~255
  • 补码表示的有符号整数:-128~+127
  • 字符、字符串(ASCII码值)
  • 压缩BCD码:0~99
  • 非压缩BCD码:0~9

字节定义示例

value1 BYTE ‘a’ ; 字符常量
value2 BYTE 0 ;最小的无符号字节常量
value3 BYTE 255 ;最大的无符号字节常量
value4 SBYTE -128 ;最小的带符号字节常量
value5 SBYTE +127 ;最大的带符号字节常量
value6 BYTE ? ;定义未初始化的变量
value7 BYTE 8 dup(20h) ;定义8个重复的字节

变量名:表示变量相对其所在段起始位置的偏移量

数组 (一条语句多个元素)
数据定义语句中有多个初始值
变量名仅仅指向第一个字节,相当于偏移地址
在这里插入图片描述
定义字符串(字符数组)
用单引号或双引号括起来的一组字符
常以空字符(NULL,0)结尾
可以占用多行,无需为每行都提供标号

greating	 BYTE “Good morning,everyone!, 0
greating1	 BYTE “Welcome to the Assembly world ”
			BYTE “created by Kip Irvine., 0dh, 0ah,
			BYTE “If you wish to modify this program”
			BYTE “send me a copy., 0dh, 0ah, 0

DUP操作符
常用于为字符串和数组分配空间
可以嵌套使用
使用常量或常量表达式表示重复次数

格式: 重复次数 DUP(重复参数)
list1 BYTE 20 DUP(0) ;20字节,全部等于0
list2 BYTE 20 DUP(?) ;20字节,未初始化
list3 BYTE 4 DUP(“STACK”) ;20字节:“STACKSTACKSTACKSTACK”
Array BYTE 3 DUP( 2,4 DUP(3,4))

使用字符常量
在这里插入图片描述
3.字量数据
定义16位变量数据

  • 16位无符号整数和16位有符号整数
  • 16位段选择器,16位偏移地址

数据含高低2个字节,占用2个连续的字节存储单元
在这里插入图片描述
小端方式&大端方式
小端方式(Little Endian)

  • 低字节数据存放在低地址存储单元
  • 高字节数据存放在高地址存储单元
    大端方式(Big Endian)
  • 低字节数据存放在高地址存储单元
  • 高字节数据存放在低地址存储单元

Intel使用小端方式的方案存取内存数据

  • 变量的最低有效字节存储在地址值最小的地址单元中,其余字节在内存中按顺序连续存储

数据的存放顺序:小端方式
在这里插入图片描述

4.双字量数据
定义32位双字量变量数据

  • 32位无符号和32位有符号整数
  • 32位偏移地址、线性地址或段基地址

数据包含4个字节,“高对高、低对低”原则占用4个连续字节空间
在这里插入图片描述
小端存储方式
在这里插入图片描述
5.变量定位
指定偏移地址 ORG 参数

  • 变量定义及指令代码的存储空间按照书写的先后顺序连续分配
  • 使用定位伪指令可以控制变量和代码存放的偏移地址
  • org 100h;从偏移地址100H处安排

对齐地址边界 ALIGN n

  • 模n地址:n字节数据起始于能够被n整除的地址
  • 2字节(16位)数据起始于被2整除的地址(偶地址)
  • 4字节(32位)数据起始于被4整除的地址(模4地址)
  • 8字节(64位)数据起始于被8整除的地址(模8地址)
  • align 4;对齐4字节地址边界

IA32处理器允许不对齐边界存放数据,但性能下降

3 .2 变量属性

变量定义做了什么工作?

  • 分配存储空间,赋初值,创建变量名

变量名具有的两类属性

  • 地址属性:变量所在的第1个存储单元的逻辑地址(段基地址:偏移地址)
  • 类型属性:变量定义的数据单位(字节数)
    字节量BYTE 字量WORD 双字量DWORD
    3字量FWORD 4字量QWORD 10字节量TBYTE

1.地址操作符
用于获取变量名的地址属性

操作符作用
[表达式]括起的表达式作为存储器地址指针
$返回当前偏移地址
OFFSET 变量名返回变量名所在段的偏移地址
SEG 变量名返回段基地址(实地址存储模型)

计算数组和字符串大小
$ 运算符返回当前程序语句的地址偏移值
字节数组大小的计算

list BYTE 10,20,30,40
ListSize=($-list)

字符串长度的计算

myString BYTE “This is a long string,containing”
BYTE “any number of characters”
myStringlen=($-myString)

2.类型操作符
指定或获得被使用变量名的类型属性

操作符作用
类型名 PTR 变量名将变量名按照指定的类型使用
TYPE 变量名返回一个字量数值,表示变量名的类型
LENGTHOF 变量名返回整个变量的数据项数
SIZEOF 变量名返回整个变量占用的字节数

4.数据寻址方式

指令组成:操作码和操作数

  • 操作码:处理器要执行的操作,用助记符表示
  • 操作数:指令执行的参与者,各种操作的对象(寻址方式),imm,reg,mem

数据寻址方式:描述数据存储位置的形式

  • 立即数寻址:数据在指令代码中,用常量表达
  • 寄存器寻址:数据在寄存器中,用寄存器名表示
  • 存储器寻址:数据在主存中,用存储器地址代表
4.1 立即数寻址

操作数紧跟操作码,是机器代码的一部分
操作数从指令代码中立即得到,即立即数(Immediate),用常量形式直接表达
立即数寻址方式只用于源操作数,常用来给寄存器和存储单元赋值
例如:MOV EAX,33221100H

  • 机器代码:B8 00 11 22 33
  • 操作码:B8
  • 立即数:33221100

在这里插入图片描述
立即数寻址
在这里插入图片描述

4.2 寄存器寻址
  • 操作数存放在处理器的内部寄存器中
  • 用寄存器名指定存储数据的位置
  • 绝大多数指令采用通用寄存器寻址
  • 部分指令支持专用寄存器,例如段寄存器
  • 寄存器寻址方式简单快捷,最常使用
    例如:MOV EBX,EAX

32位通用寄存器:EAX EBX ECX EDX
16位通用寄存器:AX BX CX DX
8位通用寄存器:AH AL BH BL

4.3 存储器寻址

操作数在主存的存储单元中,通过存储器地址指示
存储器地址使用包含段选择器和偏移地址的逻辑地址
段选择器(段寄存器)指示段基地址

  • 默认规定:数据在DS指向的数据段;EBP或ESP作为基地址,数据在SS指向的堆栈段
  • 显式说明:使用段超越指令前缀,段寄存器名后跟英文冒号

偏移地址由各种寻址方式计算,常被称为有效地址EA(Effective Address)
存储器寻址要点
操作数存在于主存的存储单元中,通过存储器地址指示
在这里插入图片描述
存储器地址构成
逻辑地址: 包含段选择器和偏移地址(EA)

  • DS:[sum] DS:[04001000]
  • 32位EA=基址寄存器+(变址寄存器×比例)+位移量

偏移地址的组成

  • 基址寄存器:32位通用寄存器
  • 变址寄存器:除ESP外的32位通用寄存器
  • 比例:1,2,4或8
  • 位移量:8位或32位有符号数
    在这里插入图片描述
    1. 段寄存器的默认和超越
    在这里插入图片描述
    主存操作数常通过变量形式引用
    一般不需要使用段超越前缀指令

    2. 偏移地址的组成
    32位有效地址=基址寄存器+(变址寄存器×比例)+位移量
  • 基址寄存器:32位通用寄存器
  • 变址寄存器:除ESP外的32位通用寄存器
  • 比例:1,2,4或8
  • 位移量:8位或32位有符号数

3.直接寻址(直接内存操作数)
32位EA=位移量
32位EA=基址寄存器+(变址寄存器×比例)+位移量

  • EA(位移量)直接包含在指令代码中
  • 用途:存取变量,对应C/C++语言的变量
    在这里插入图片描述

直接寻址图示
在这里插入图片描述
4.寄存器间接寻址
32位EA=基址寄存器
32位EA=基址寄存器+(变址寄存器×比例)+位移量

  • EA存放于指定的寄存器内,寄存器用[ ]括号括起
  • 用途:对数组元素进行访问操作,类似于C/C++的指针

在这里插入图片描述
5.寄存器相对寻址
C/C++数组访问:array1[i]
32位EA=基址寄存器+位移量
32位EA=基址寄存器+(变址寄存器×比例)+位移量
用途:访问数组元素

在这里插入图片描述
6.变址寻址

比例变址寻址32位EA= (变址寄存器×比例)
相对比例变址寻址32位EA= (变址寄存器×比例)+位移量
基址比例变址寻址32位EA=基址寄存器+(变址寄存器×比例)
相对基址比例变址寻址32位EA=基址寄存器+(变址寄存器×比例)+位移量
基址变址寻址32位EA=基址寄存器+(变址寄存器)
相对基址变址寻址32位EA=基址寄存器+(变址寄存器)+位移量

使用变址寄存器寻址操作数
用途: 数组等数据结构的访问
基址寄存器Eax,ebx,ecx,edx,esi,edi,ebp,esp

  • 变址寄存器Eax,ebx,ecx,edx,esi,edi,ebp
  • 比例:1、2、4和8

比例=2,4,8的变址寻址
用途: 便于以数组元素为单位寻址相应数据
在这里插入图片描述
二维数组的访问
在这里插入图片描述

4.4 数据寻址的组合
  • 立即数寻址 imm(通用)
  • 寄存器寻址 reg
  • 存储器操作数寻址 mem

在这里插入图片描述
指针
包含其他变量地址的变量称为指针变量或指针。

基于Intel的程序使用两种基本类型的指针:NEAR和FAR。
16位模式32位模式
NEAR指针相对数据段开始的16位偏移地址相对数据段开始的32位偏移地址
FAR指针32位的段-偏移地址48位的段-偏移地址

保护模式程序使用NEAR指针,所以被存储在双字变量中。
定义指针

arrayB BYTE 1, 2, 3, 4
arrayW WORD 1, 2, 3
ptrB DWORD arrayB ;ptrB包含arrayB的偏移地址
ptrW DWORD arrayW ;ptrW包含arrayW的偏移地址
还可以使用OFFSET操作符,更清晰:
ptrB DWORD OFFSET arrayB
ptrW DWORD OFFSET arrayW

TYPEDEF 与TYPEDEF PTR操作符
类型的声明一般置于程序的开始处,在数据段之前
TYPEDEF用于创建用户自定义类型

BOOL TYPEDEF DWORD
UINT TYPEDEF DWORD
LONG TYPEDEF DWORD

TYPEDEF PTR用于定义指针类型

  • 创建指向字节的指针PBYTE
		PBYTE TYPEDEF PTR BYTE
.data
		arrayB BYTE 10h, 20h, 30h, 40h
		ptr1 PBYTE ? ;未初始化
		ptr2 PBYTE arrayB ;指向数组

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值