小白进阶之路之汇编5

title:x86汇编语言之8086语法和指令集
tags:汇编

小白进阶之路之汇编5(持续更新中)

x86汇编语法

  1. 注释

    ;注释

  2. 变量取值和赋值(传送指令)

    ;赋值
    mov ax,2000H ;将十六进制2000赋值给十六位寄存器ax 相当于ax=2000H
    mov bx,FFFFh
    ;取值
    mov bx,ax ;将ax中的值取出赋值给bx 相当于bx=ax

存放的数据大小根据使用的寄存器而定,比如ax是16位寄存器,最大只能存放16位数,也就是4位十六进制数据

十六进制数据不能以字母开头,前面需加上0 否则编译错误

  1. 函数声明

结构如下:

函数名:
	函数体
	ret ;结尾标记

示例:

print ;函数名
	mov dx,offset str
	mov ah,9ch
	int 21h
	
	ret ;函数结尾标记
  1. 函数调用

x86架构中使用关键指令call

x86架构汇编示例:

	call print ;调用print函数
	
	;退出程序
	mov ah,4ch
	int 21h
	
print:  ;函数名
	mov dx,offset str;获取别名对应数据的偏移地址
	mov ah,9ch;9h表示调用显存 从dx总读取偏移地址对应的数据
	int 21h
	ret
  1. 字符串的定义

起因:如果直接将字符串赋值给通用寄存器,会出现以下两个问题:

  • 字符顺序是反着的
  • 最多只能存放两个字符
  • 无法获取到数据地址,不能堆字符串进行修改

为了解决这个问题,需要使用另外一种方式,定义字符串

  • 首先需要先在内存中申请一块空间,可以使用伪指令db和dw

    db–>define byte 定义字节
    dw–>define word 定义字

  • 示例

    db ‘hello’ ;占用五个字节的内存空间
    dw ‘hello’ ;占用六个字节的内存空间

如果定义数字,使用dw每个数字占用两个字节的空间,字符串比较特殊,并不是每个字符占用两个字节,而是总长度必须是2的倍数

  1. 字符串的获取

获取字符串的数据,首先要获取到数据所对应的内存地址

那怎么获取已经定义好的地址呢?

第一步尝试:给数据添加别名

str db 'hello'
start:
	mov bx,str;别名中存放的是偏移地址
end start

别名中存放的是偏移地址,但是光有偏移地址还不行,还需要段地址,段地址+偏移地址=实际物理地址,别名默认从ds寄存器中读取段地址,但是我们并没有给ds寄存器赋过值,这就导致我们无法获取正确的数据,因为我们不知道正确的段地址是多少?

那字符串段地址从哪里获取呢?

  • 方法一:直接从内存中找(仅限于调试,实际开发肯定不行)
  • 方法二:使用段进行包裹,段能给我们提供一个段地址(正解)
 data segment
    	str db 'hello'
    data segment
    	;使用段进行包裹,可以借助段名称获取段地址
    
  1. 对内存中的数据进行读写

从内存中一次读取数据的多少,取决于寄存器的容器大小

data segment
	str dw 'hello','pangshu';如果定义多个数据,使用逗号进行分隔
data ends

start:
	mov ax,data
	mov ds,ax
	mov ax,str;如果从内存中读取数据,是根据寄存器大小来读取,16位寄存器则一次性读取16位数据,8位寄存器则一次性读取八位数据
end start

错误写法:

;报错1
data segment
	str db 'hello';改成dw则不报错
data ends
start:
mov ax,data
	mov ds,ax
	mov ax,str;
	
end start
;报错2
data segment
	str dw 'hello'
data ends
start:
mov ax,data
	mov ds,ax
	mov al,str;改成mov,ax,str或者mov,al,b,str则不报错
	
end start

内存数据的读写从低到高

上面使用db或者dw定义数据的方式吧,定义数据的同时就已经定义好了数据所在的物理地址,如果我们想要从指定的内存地址中写入或者读取数据的话,需要借助段寄存器来实现,在8086中给我们提供了DS SS CS ES四个寄存器,理论上使用哪一个都行,但是由于系统默认读取DS寄存器中的数据当做段地址,所以我们一般使用DS进行数据的段地址管理

  • 如何从指定内存中读取数据

假设我们需要从0710:0000这个物理地址中读取数据,然后存放到寄存器中

错误写法1:
start:
	mov ax,0710:0000;没有这种语法
end start
错误写法2:
start:
	mov ds,0710H;段寄存器不能直接赋值,必须借助通用寄存器
	mov ax,ds:[0]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值