汇编知识扫盲之16位汇编跟32位汇编的保护模式以及汇编代码编写
一丶内存寻址模型
逻辑地址.线程地址.物理地址
了解汇编之前.先了解一下上面这些词的含义;
逻辑地址: 这个是邮编一起生成的.逻辑地址一般都是 段加段内偏移组成的.每个进程独享.
线性地址: 由分段管理机制.将逻辑地址转化为线性地址.这个了解即可.学过内核的人看到应该明白.如果没有学过.简单滤过即可(32位下逻辑 = 线性)
物理地址: 通过分页管理机制(内核中成为PDE PTE等页目录 页表等等)将线性地址转化为物理地址. 这些了解即可.
下图说明了上面三个地址的意思:
这张图学过内核的能看明白. 如果没学过.那么了解即可.
二丶实模式分段模型.跟保护模式扁平模型
如果细说这两个的区别会很多.不过我们了解下即可.
实模式分段模型.:
有20位地址总线
每个段的大小是64kb
16个不同的段.
CS DS寄存器中保存的是段的起始地址.
上面主要就是说. 我怎么寻找逻辑地址. 其实就是段 偏移的方式.
16位下. 有 2^16次方寻址. 也就是64kb. 但是增加了4条地址总线.也就是 2^20次方 = 1MB
那么为了寻到这1MB的空间. 首先就把1MB空间分成16个不同的段. CS DS存放段的起始地址. 然后加上段内偏移即可寻到.
保护模式扁平模型
32个地址总线.
引入了GDT LDT等段描述符表
CS DS不变.
因为32位地址总线可以存储地址了.所以段寄存器就都为0了.但是是保护模式.所以引入了段选择子. (涉及到内核知识了) 这些了解即可.
三丶16位代码编写.
16位我们要自己分段.自己写代码. 下方代码是一个16位汇编程序.
代码语言:javascript复制data segment ;定义数据段
str db 'HelloWorld$' ;以字节方式在数据段中定义字符串
data ends ;数据段结束
code segment ;定义代码段
assume cs:code ,ds:data ;将CS寄存器跟代码段相关联.DS寄存器跟数据段相关联
start: ;定义标号.代码开始执行位置.
mov ax,data ;将数据段给ax寄存器保存
mov ds,ax ;将ax给DS寄存器保存.
lea dx,str ;求得字符串的地址
mov ah,9h ;调用21号功能的9h功能进行打印
int 21h
mov ah,4ch ;调用4ch进行退出
int 21h
code ends ;代码段结尾.
end start ;结束位置.必须给标志表示从哪里开始执行
16位汇编是运行在以前的老机器上的.所以我们需要下载两个软件才能进行编译执行.
一个是MASM5.0 一个是 DOSbox 0.74 下方附上链接
链接:https://pan.baidu.com/s/1O0-mUWv9fgvkqA_An1W0yA 密码:xzjd
使用DOSbox0.74 的步骤
代码语言:javascript复制1.解压MASM5.0到你的盘符
2.安装DosBox0.74
3.打开DosBox0.74
4.在DosBox中使用指令切换到你的MASM盘符
例如: mount d: d:MASM5.0
5.切换盘符 D:
6.DIR命令观看是否设置成功
7.编译你写的16位汇编
masm a.asm
8.编译之后会生成obj.我们还需要进行连接
link a.obj
9.连接之后就生成了a.exe了我们可以直接运行
a.exe
10.如果调试则使用 debug a.exe进行调试.
使用masm编译的时候.确保asm放在masm目录下面.
结果演示.
四丶32位汇编代码编写.
32位汇编代码编写.可以使用RadAsm编写.博客中已经写过.我们主要讲解一下在VC中的写法.
在VC中32位下.可以支持内联汇编的.
例如:
代码语言:javascript复制__asm
{
push eax
push ebx
pop eax
pop ebx
}
五丶64位汇编写法
64位汇编已经不支持我们使用内联汇编了.所以我们必须要添加ASM去编写.
这有一篇好的文章: https://www.mallocfree.com/basic/asm/asm-4-x64.htm