「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
x86汇编语法
- 注释
;我是注释
- 变量取值和赋值(传送指令)
;赋值
mov ax,2000H ;将十六进制2000赋值给十六位寄存器ax 相当于ax=2000H
;取值
mov bx,ax ;将ax中的值取出赋值给bx 相当于bx=ax
存放的数据大小根据使用的寄存器而定, 比如ax是16位寄存器,最大只能存放16位数据,也就是4位十六进制数据
十六进制数据不能以字母开头, 前面需加上0 否则编译报错
- 函数声明
结构如下:
函数名:
函数体
ret ;结尾标记
示例:
print: ;函数名
mov dx,offset str
mov ah, 9ch
int 21h
ret ;函数结尾标记
- 函数调用
x86架构中使用关键指令call
x86架构汇编示例:
call print ;调用print函数
;退出程序
mov ah, 4ch
int 21h
print: ;函数名
mov dx,offset str;获取别名对应数据的偏移地址
mov ah, 9ch ;9h表示调用显存 从dx总读取偏移地址对应的数据
int 21h
ret
-
字符串的定义
起因:如果直接将字符串赋值给通用寄存器,会出现以下两个问题:
- 字符顺序是反着的
- 最多只能存放两个字符
- 无法获取到数据地址,不能堆字符串进行修改
为了解决这个问题,需要使用另外一种方式,定义字符串
首先:需要先在内存中申请一块空间,可以使用伪指令db和dw
db-->define byte 定义字节 读写一个数据,偏移量加1 dw-->define word 定义字 读写一个数据,偏移量加2 dd-->define double word 定义双字, 读写一个数据 偏移量加4-
示例
db 'hello' ;占用五个字节的内存空间 dw 'hello' ;占用六个字节的内存空间 跟偏移量有关系
如果定义数字,使用dw每个数字占用两个字节的空间, 字符串比较特殊,并不是每个字符占用两个字节,而是总长度必须是2的倍数
-
字符串的获取
获取字符串的数据,首先要获取到数据所对应的内存地址
那怎么获取已经定义好的地址呢?
第一步尝试: 给数据添加别名
str db 'hello' start: mov bx,str ;别名中存放的是偏移地址 end start别名中存放的是偏移地址,但是光有偏移地址还不行,还需要段地址, 段地址+偏移地址=实际物理地址,别名默认从ds寄存器中读取段地址, 但是我们并没有给ds寄存器赋过值, 这就导致我们无法获取正确的数据,因为我们不知道正确的段地址是多少?
那字符串段地址从哪里获取呢?
-
方法一: 直接从内存中找(仅限于调试,实际开发肯定不行)
-
方法二:使用段进行包裹, 段能给我们提供一个段地址(正解)
data segment str db 'hello' data ends ;使用段进行包裹, 可以借助段名称获取段地址 start: mov ax,data mov ds,ax mov bx,str end start
-