16位汇编语言第二讲系统调用原理,以及各个寄存器详解

昨天已将简单的写了一下汇编代码,并且执行了第一个显示到屏幕的helloworld

问题?

  helloworld怎么显示出来了.

一丶显卡,显存的概念

1.显示hello就要操作显示器,这是非常原始的,那个时候的程序员,并没有像现在的RGB(红绿蓝)这样的三色真彩色,那个时候就是操作显卡的,定义了一个标准

这个标准就是我们要往固定的地址写入数据,就会显示出来

具体流程

操作显卡 -> 显卡有自己的缓存 -> 把数据写入到显存中, - > 显示数据 (显示到屏幕上)

但是那个时候是没有字的,所以就开始造字,那个时候就是把英文的26的英文字母做出来颜色都是一样的

比如 我们造一个1,并且把它放到显存中

0 0 1 0 0

0 0 1 0 0   把这个1看做是一个二维数组,把这块数据放到显存中就会显示1了.

0 0 1 0 0

二丶锯齿的概念

我们发现,很多游戏中都有一个选项,叫做坑锯齿

其实锯齿是因为,以前做 1的时候,颜色就是黑白的 这样的字就有一点点的齿痕.看着不舒服,所以后边,就用三色,把和一个字相同颜色的都放在一起

这样看的字就很平滑,很好看.

可以看出,我写了一个 1字,放大后旁边的像素有蓝色的,红色的黄色的等等,而以前的就是黑色一种,所以看着很难看.

三丶系统调用原理

比如我们想显示一个字符串,直接 "hello"双引号包含起来,给操作系统即可.就会显示了.

那么原理是什么.

  第一讲中,说了一个指令字典,里面有功能号 int 21代表我们要调用那一项,而硬件是提供了一个表格,调用的时候直接查表

这个表格是函数指针数组,直接调用即可.

例如

但是我们会想,操作系统会调用这第21项显示数据,那么这个表可能是无限的大的吗,而操作系统提供的api就要好几万个,怎么一个表够用吗

所以后面有了ah寄存器传参,上面的图可以改为

当然可能不用Switch这种低效率的语法,会做优化,但是原理就是这样,硬件厂商只提供指令,就是说我cpu一定会调用int 21指定,找到数组中的第21项

而 这个表格则是操作系统提供的.

所以现在就知道,什么是 int 21,和为什么ah给9才能显示字符串了吧.

四丶新的问题系统没有启动之前就会显示字符串

我们有没有发现,系统还没有启动之前,就会显示一段字符串,这个字符串是通过主板的bios显示的

bios是不依赖于系统的,优先于系统存在.

操作系统启动之后也可以调用

在指令字典中

在中断码中会有说,调用int 多少,参数通过什么寄存器给.等等. 他和cpu的那种表是不一样的,但是都存在于操作系统启动之前.

五丶寄存器详解

1.IP指令寄存器

IP寄存器,上一讲说过,IP寄存器适合CS段寄存器一起使用的,IP是偏移(ip寄存器叫做指令寄存器) 他是表示通过cs段寄存器 + IP的偏移,来确定下一条指令执行的位置

比如我们有一段汇编代码

下一条指令执行的执行的位置是0100 ip就等于0100,可以用p指令查看. 其实ip等于0100是代表ip的偏移是0100,用cs段寄存器 * 16 + ip的偏移,就等于实际物理地址(也就是下一条指定指令的位置)也就是 mov ax,1

p指令调试查看

第一次

第一指令位置的偏移是0103 也就是 mov bx,2会开始执行,下面一次类推(不懂段寄存器,下面细讲)

2.Flag标志寄存器

标志寄存器的好的博客简介连接  https://my.oschina.net/clownfish/blog/142328

上一讲也说了flag标志寄存器释放各种标志的, flag标志器是16位

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
        OF DF IF TF SF ZF   AF   PF   CF

通常标志器是9个,常用的有6个,不常用的有三个,说下不常用的吧 DF IF TF,其余就是常用的了

CF 进位标志( Carry Flag) :

当我们做加法运算的时候,比如两数相加 结果是否进位了

进位的时候,标志就是1,否则标志就是0,如果是加法运算,那么标志位1代表进位,如果为减法,那么标志为借位

比如 3AH + 7CH = B6H (h在汇编中代表前边的数字是16进制) 没有进位CF = 0

AAH + 7CH = (1) 26H,最高位进位了,CF = 1

ZF 零标志(Zero Flag):

表示你运算的结果为0,则ZF = 1,如果不为零则ZF = 0

例子:  

  3AH + 7CH = B6H,结果不为零,ZF = 0

  84H + 7CH = (1) 00H,结果是0,因为进位了,那么CF = 1

SF 符号标志位(sign flag):

表示运算的结果,最高位为1,则SF为1,否则最高位不为1 SF = 0

3AH + 7CH = B6H,结果的最高位不为零,以为B看做二进制的则是 1 0 1 1 最高位是1所以 SF = 1

84H + 7CH = (1) 00H,结果是0,最高位是0

PF 奇偶标志位 (Parity Flag)

表示你运算的结果中,统计1出现的个数(二进制的统计)如果1的个数为零,或者偶数的时候,则PF = 1,奇数则是0

比如

3AH + 7CH = B6H, = 1011 0110 B(后缀B代表二进制的意思) 统计个数,出现了五个1则PF = 0;

OF 溢出标志位(OverFlow Flag)

若运算结果有溢出(或者结果不正确)则OF = 1,否则OF = 1

比如

3AH + 7CH = B6H 产生了溢出, OF = 1

AAH + 7CH = (1) 26H,进位了,但是没有溢出,OF = 0

1.溢出

  在8位表达的整数返回的时候 是+127 -> -128

  在16位表达的范围内是: +32767~ -32768

  比如 3AH + 7CH = B6H,在八位范围中 3A = 10进制的58 7C = 十进制的124

  那么结果就是58 + 124 = 182,远远超过了128的范围,所以产生了一出,并一方面

  B6H的结果变成补码,其值就是-74,显然结果也是不正确的

2.溢出和进位的不同

  溢出标志OF,和进位标志CF是不同的,

极为标志表示无符号数运算的记过是否超出范围,其运算结果仍然正确

溢出标志表示有符号数的运算结果是否超出了范围,运算的结果已经是不正确了.

3.如何运用溢出和进位

这个取决于程序员

当处理器对两个操作数进行运算的时候,会按照无符号的数据求得结果(为什么是无符号,因为负数有补码)

并且设置进位标志位CF,同事,根据是否超出有符号数的范围设置一处标志OF,也就是说也会设置进位,也会设置溢出标志位,设置溢出标志位的原因是无符号数已经超过了范围了.

利用那个标志取决于程序员自己决定

4.溢出的原理判断

简而言之就是 正数加正数等于正数,但是此时结果的二进制最高位为1(1是负数的意思)那么计算机就认为产生了一出

AF 辅助进位标志(Auxiliary Carry Flag)

辅助标志位主要表示的是低4个的进位或者借位,和CF不同,CF是八位产生进位和借位才会设置标志位

所以这个为辅助进位标志位

比如:

3AH + 7CH = B6H,低四位有进位,则AF = 1

DF 方向标志位(Direction Flag)

比如我们的SI 和DI 变址寄存器如果要memcpy的时候,内存会增加或者减少.

DF就是控制地址的变化的方向的

DF = 0,则存储器地址自动增加

DF = 1,则存储器的地址自动减少

汇编中的CLD指令,表示复位方向标志,让其DF = 0,地址自动增加

汇编中的STD指令,表示置位方向标志,DF = 1,表示地址曾东减少.

IF 中断允许标志(Interrupt - enable Flag)

官方语言: 用于控制外部可屏蔽中断是否可以被处理器响应

自己理解的

比如键盘按下,怎么知道按下的,以前是无限循环,但是效率特别低,现在改成了键盘按下就会像CPU发送一个信号

CPU正在执行指令的时候,你按了一下键盘,会先放弃当前指令,去执行键盘发送过来的按键指令,但是如果我们一直按着键盘不放,是不是当前的指令就执行不了了,所以我们设置标志即可屏蔽当前发送过来的指令

汇编指令 CLI指令复位中断标志IF = 0;

汇编指令 STI指令置为中断标志: IF = 1

IF = 1,则代表我们可以允许中断(也就是屏蔽指令)

IF = 0,则IF 禁止中断

TF 陷阱标志(Trap Flag)

用于控制处理器进入单步操作方式(一般调试器才会用到)

TF = 0,处理器正常工作

TF = 1,处理器单步执行指令

利用这个标志,可以对程序进行逐条指令的调试.

这种逐条指令的调试程序的方法就是单步调试,

没有汇编指令,如果设置,则用 位运算 | 上即可.

二丶段寄存器以及存储器

1.存储器和段寄存器

简而言之

  说的就是寄存器是cpu内部的内存

  内存可以存放外部数据

  硬盘可以存放外部数据,断电后还会存在

2.数据的表达单位

  二进制 bit 0 1 组成

  字节 byte 8个bit位组成

  字 word 16位 : 2个字节组成

  双字DWord 32位,两个字组成

分为大端模式存储,和端模式存储

官方语言是 LSB,MSB等等.小尾方式,和大尾方式

大端模式:  低位放低位地址,高位放到高位地址

低地址 - -------- 高地址 (比如存放1 2 3 4)

0x1  0x2   0x3  0x4

小端模式

低位放高地址,高位放低地址

低地址 - -------- 高地址 (比如存放1 2 3 4)

0x4 0x3 0x2 0x1

3.存储单元和存储内容

 每个存储单元都有一个地址编号,被称为存储器的地址,在C语言中其实就是内存地址

每个存储单元都存放了一个字节的内容.

如果取内容则是

[地址] = 取出来的值,所以C语言中的数组的中括号就是这样来的.

4.解决CP的寻址能力

16位处理器,能处理最大的数据范围是2^16次方数据,也就是64k,就算你装上一个1MB的内存也访问不到

解决:

  1.8086CPU有20条地址线,最大的可寻址的控件是2 ^20次方,威力地址从00000h - FFFFFh

  2.8086CPU讲1MB的空间分为了很多逻辑段(Segment)

    每个段的最大限制为64kb,为什么,因为寄存器是16位了,没次寻址都是2 ^16次方

    短地址的低四位为0000b,为什么,因为加了4根地址总线,也就是多了4个,所以都给4

 这样,一个存储单元,除了有一个唯一的物理地址,还有很多的逻辑地址

现在为了解决这个寻址问题,所以用2个寄存器存储,也就是上面为什么说CS和IP一起来确定一条物理内存执行

的下一条指令了.

而逻辑地址有很多,分了好几段,也就是段地址了, 采用段基地址 : 段内偏移地址 这样存储

段地址: 段地址就是逻辑地址在主存的起始位置

  8086规定段的地址必须是%16, 那么地址就是xxxx0H,因为是16进制,所以最后为0,换算成二进制就是后面4个二进制为0

  因为%16地址,所以现在就能用16位的段寄存器来表示段地址了.

偏移地址

  偏移地址说明主存单元距离段地址起始位置的偏移量

  每段也是不超过64kb,也可以用寄存器存储,所以 IP就出现了

物理地址和逻辑地址的转换

讲逻辑地址(段地址)左移4位(也就是 *2^4次方)加上偏移的地址,就得到了20位的物理地址

一个物理地址可以有多个逻辑地址

比如

逻辑地址 1460 : 100 物理地址就是14600 (因为*16) + 上偏移100 = 14700H

1380: F00  = 13800 + F00 = 14700H

8086中常用的段寄存器

CS(代码段) 指定代码段的起始地址

SS (堆栈段) 指明了对斩断的起始地址

DS (数据段) 指明了数据段的起始地址

ES(附加段) 指明了附加端的起始地址

而这些在C语言中称为内存4区

为什么分段:

  我们上一讲写的显示Helloworld并且写到文件中,现在汇编的代码和数据是在一起的,但是一旦程序更大了,就不好弄了.

作业: 使用debug编译器,利用指令,查看标志位的状态显示分别是什么

第二讲作业以及工具获取连接

链接:http://pan.baidu.com/s/1mi3KW1U 密码:0u0e

时间: 2024-11-10 07:26:25

16位汇编语言第二讲系统调用原理,以及各个寄存器详解的相关文章

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数 (如果想看所有代码,请下载课堂资料,里面有所有代码,这里会讲解怎么生成一个窗口程序) 一丶32位汇编编写Windows窗口程序 首先我们知道32位汇编是可以调用Windows API的,那么今天我们就调用windowsAPI来写一个窗口程序 如果你有windows开发知识,那么就很理解了,如果没有,那么跟着我写,跟着步骤去写,那么也可以写出来 首先我们要编写一个窗口程序(使用SDKAPI编写)有几个步骤 1.设计窗口类 2.注

FTP服务器工作原理的及配置详解

FTP服务器工作原理的及配置详解 FTP工作原理概述 FTP:file transfer protocol 它也是一个C/S架构的服务.server:监听在套接字21/tcp端口.按照套接字监听工作状态可以分为两类: 命令连接:发送文件管理类命令,始终处于连接状态,始终监听在21/tcp端口. 数据连接:主要是实现数据传输,这种连接是按需连接的,而且在传输结束会立刻中断. 对于数据连接还有两种不同的工作模式: 主动工作的模式:服务器根据监听在21端口接收到的命令,使用自己的20号端口,将数据传输

使用LVS实现负载均衡原理及安装配置详解

转:http://www.cnblogs.com/liwei0526vip/p/6370103.html 使用LVS实现负载均衡原理及安装配置详解 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学习 LVS 并对其进行了详细的总结记录. 一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director

使用 LVS 实现负载均衡原理及安装配置详解

使用 LVS 实现负载均衡原理及安装配置详解 来源:肖邦linux 发布时间:2017-02-19 阅读次数:106 0 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学习 LVS 并对其进行了详细的总结记录. 一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用

Scala 深入浅出实战经典 第78讲:Type与Class实战详解

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2土豆:http://www.tudou.com/programs/view/2vZ06RMcD6I/优酷:http://v.youku.com/v_show/id

Linux系统调用--getrlimit()与setrlimit()函数详解

http://www.cnblogs.com/niocai/archive/2012/04/01/2428128.html 功能描述:获取或设定资源使用限制.每种资源都有相关的软硬限制,软限制是内核强加给相应资源的限制值,硬限制是软限制的最大值.非授权调 用进程只可以将其软限制指定为0~硬限制范围中的某个值,同时能不可逆转地降低其硬限制.授权进程可以任意改变其软硬限制.RLIM_INFINITY的 值表示不对资源限制. 用法: #include <sys/resource.h>int getr

NFS服务器原理和安装配置详解附案例演练

NFS服务器原理和安装配置详解附案例演练 1.什么是NFS服务器 NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器.不同的操作系统可以共享彼此的文件. NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利: 2.NFS挂载原理 NFS服务器的挂载结构图: 如上图示: 当我们在NFS服务器设置好一个共享目录/home/public后

java多线程模式ThreadLocal原理简述及其使用详解

原创整理不易,转载请注明出处:java多线程模式ThreadLocal原理简述及其使用详解 代码下载地址:http://www.zuidaima.com/share/1781557457128448.htm ThreadLocal是为了使每个线程保存一份属于自己的数据. 先看一个使用ThreadLocal的实例. package com.zuidaima.aop.framework; import com.zuidaima.core.NamedThreadLocal; public abstra

log4CXX第二篇---配置文件(properties文件)详解

一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置. 1.Loggers Loggers组件在此系统中被分为六个级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL.这六个级别是有顺序的,分别用来指定这条日志