汇编--汇编学习记录日志

汇编学习记录日志:
1.显存段地址 B8000H-BFFFFH  753664- 786431    32767 共32K内存
  寻址,就是寻找指令中操作数的地址,
  寻址方式,就是找到操作数的方式,指令要进行操作,都有相应的数据参加,可是数据在哪里?是什么?都是通过不同的寻址方式来找到的。
  学习寻址方式,是为了找到指令中参与操作的数据,然后根据指令,得出结果。

2.分配一个地址的时候,如何知道这个地址是否被使用?

  内存分配? 这个数据结构有关,我们都知道数组结构申请的是一整块连续的内存,而链式结构是逻辑上的连续内存。
  如何分配连续内存和不连续内存?因为不连续内存多了就会导致需要连续内存的时候就会没有内存可分配了。
  导致内存零散。每个进程有一块独立的内存空间。os对进程的管理是给每个进程申请一个独立的内存,该进程的内存的分配只能
  在该进程之内。所以如果一个进程所需内存过大就会导致过慢,因为内存无法满足,这时候就是要把一部分数据无关的程序退出来
  然后交换需要的程序,交换算法。

内存池技术解决内存碎片问题还有解决因为频繁申请内存和释放内存的效率问题,只有在内存池需要扩张的时候申请内存。
把大内存分割,然后在小内存内进行分配,就减少大内存的碎片产生和清理。


3.os对内存管理: 段  分页 

4.汇编寄存器-内存   :寄存器  ax 是累加器  
                               bx是基址寄存器  
                               cx和loop一起使用 
                               dx
                               cs是代码段  和ip一起 cs:ip
                               ss:sp是堆栈段,作为堆栈寄存器
                               ds是数据段  一般默认计算物理地址的段地址
                               dw 定义字,在高级语言来说就是定义数组。。定义字  双字,申请一连串连续的内存
5.寄存器寻址: 就是从内存把数据找到送给寄存器
            直接数寻址   寄存器直接寻址  基址寻址   基址变址寻址  


6.push  入栈: push指令操作的原理:
    因为ss:sp栈段寄存器存放了栈顶的指针,push的时候    ss:0000 指向了栈底 ss:sp指向了栈顶  ,这就构成了一个堆栈,堆栈是一块连续的内存
    sp=sp-2,ss:sp指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
    将ax中的内容送入ss:sp指向的内存单元处,ss:sp此时指向新栈顶

   pop ax
   将ss:sp指向的内存单元出的数据送入ax中
   sp=sp+2,ss:sp指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
   push ax  是把ax的数据送入栈顶指针指向的数据
   pop ax  把ss:sp指向的数据送入ax

7.pc寄存器就是程序计数器
 jvm虚拟机放弃了其他的寄存器,而是使用操作数栈,对数据进行入栈出栈,然后送往运算器。


8.汇编对磁盘的读写,通过int 13h这个中断列程来实现的,我们只需要负责说明是读还是写,磁盘的存储位置
  还有需要读写的数据
  mov ax  OFFFH  OFFFH 这种是立即数,当汇编执行指令到这时候,OFFFH这数据是存在于指令流中,而不是存在于内存中
 直接把指令流中的0FFFh送入到ax中

assume code:codesg
    codesg  segment 定义段

   mov ax,0123H
   mov bx,0456H
   add  ax,bx
   add ax,ax 
  codesg ends  段结束
  end   程序结束

assume  data:datamsg  ,code:codesg
datamsg  segment 
dw 0123H,0456H
datamsg   ends
codemsg  segment 
 start:mov ax,0123H
   mov bx,0456H
   add  ax,bx
   add ax,ax 
  codesg ends
start end  //start 表示程序入口

9.寻址:表示数据的位置在哪: 1.指令中 2.寄存器 3.内存”
  byte 和word 表示要处理的数据多长  字节和自  字节 8位,字16位

  mov  byte ptr ds:[0],1
  push 默认只进行字操作

  db定义字节型数字
  dw定义字型数据
  dd定义双字
  dup配合db dw dd
  db 3 dup(0)  定义了三个字节 他们的值都是0 ,db 0 ,0 ,0

10.转移指令: cs:ip 可以修改ip或者同时修改cs和ip的指令统称为转移指令


  jmp ax  段内转移 
  jmp  1000:0  段间转移


  端转移和近转移:
  短转移IP的修改范围:-128-127
  近转移 -32768 -32768

  转移指令: 无条件转移: jmp
  条件转移: 
  循环指令: loop 
  过程
  中断  int 21H

11 offset  取得标号的偏移地址
  assume  cs:codesg
  codesg segment 
  start : mov ax,offset start   //相当于mov ax ,0
         s:mov ax,offset s   //相当于mov ax,3
  codesg ends
  end start 

  assume  cs:codesg
  codesg  segment 
  start :mov ax,0
  jmp  short s 
  add ax,1
  s:inc ax
  codesg ends
  end start


 jcxz: 的功能相当于:  if ((cx)==0) jmp short 标号

12.内中断:
  1.取得中断类型码N
  2.push  f  入栈,把当前cs:ip的值入栈
  3.设置标志寄存器的值: TF=0 IF=0
  4:Push  CS 
  5:Push IP
  6:ip=(N*4) cs=(N*4+2)  计算cs:ip的值,然后cpu执行这个地址的指令

  7:中断处理程序执行完后用iret指令返回,iret指令的作用是:
  pop  ip
  pop  cs
  popf

13 div指令: 
   当除数是字节 也就是8位的时候  被除数必须是16位  被除数存放在ax寄存器中  除数放在bl中

   除到得 结果是 商是8位放在al中 余数放在ah中

  例子

  mov ax,0006h

  mov bl,02h

  div bl

  int  指令  int n  执行N号中断,
  1,取中断类型码N
  2,标志寄存器入栈,IF=0 TF=0
  3.  CS ip 入栈  保存中断程序执行完后,继续执行的指令代码
  4,IP=N *4 cs =n*4+2  计算指针将要跳转的地址,然后执行中断程序。


  while (c<0){

  }
 //循环八次
mov cx 8 
s: add ax ,8
loop s


14:我们所说的申请内存是向操作系统申请内存,而汇编可以不通过操作系统申请内存而是直接对内存操作,但是有些内存区域是安全的,就比如中断向量表哪里
这段内存是不允许往里面写东西的。否则将会引起死机。

中断向量表 0-1023   0000:0000-0000:03ff 这1023个内存中
                                0000:0200-0000:02FF  512到767这个内存中是空的,可以往里面写东西。
256 个中断向量表
0000:03ff   这个叫逻辑地址  =段地址+ 偏移地址

如何用汇编定义结构体,数组,if  for 循环 

for 循环可以是 loop指令
段地址 :偏移地址
SS:SP    ss堆栈段地址 sp 指针寄存器 bp也是   BX 默认是ds  DS:BX
0000:0000   FFFF:FFFF

00000+0000   FFFF0+FFFF
0-1048576    1M


15:为什么要使用段: 如果程序需要用其他空间来存放数据,使用哪里呢?0:200-0:2ff是相对安全的,但是
这段空间的容量只有256个字节,如果超过256个字节怎么办?

定义段来进行内存空间的获取。
要一个程序在被加载的时候取得所需的空间,则必须要在源程序中做出说明,
我们通过在源程序中定义段来进行内存空间的获取。


执行一个程序 各个寄存器初始值:

7333                            289                            64
AX=1ca5    BX=0000   CX=0121  DX=0000  SP=0040 BP=0000 SI=0000 DI=0000 
7317             7317        117471     7346              3
DS=1c95    ES=1c95    SS=1cae  CS=1cb2   IP=0003  NV  UP DI Pl  NZ  NA PO  NC
icb2:0003 8ed8   mov ds,ax

内中断有四种
  除法错误
  单步执行
  执行into指令
 执行int指令
端口:各种存储器都和cpu的地址线数据线,控制线相连,cpu在操控他们的时候,把他们都当做
内存来对待。把他们总的看做一个由若干存储单元能组成的逻辑存粗气
这个逻辑存储器我们称其为内存地址空间。
在pc机系统中,和cpu通过总线相连的芯片除各种存储器外还有以下三种芯片

1.各种接口卡, 网卡,显卡 的接口芯片,他们控制接口卡进行工作
2,主板上的接口芯片,cpu通过他们对部分外设进行访问
3,其他芯片,用来存储相关的系统信息,或进行相关的输入输出处理
在这些芯片中,都有一组可以由cpu读写的寄存器,这些寄存器,他们在物理上可能处于不同的芯片
但是他们在一下两点上相同
1.都和cpu的总线相连,当然这种连接是通过他们所在的芯片进行的
2.cpu对他们进行读或写的时候都通过控制线向他们所在的芯片发出端口读写命令


键盘输入: 引发9号中断

内存地址空间:cpu能直接读写的设备只有寄存器  内存  端口,
寄存器和内存都好理解,寄存器本身就是cpu的一部分,内存有译码驱动和解码驱动
但是显卡啊,网卡啊之类的和cpu之间进行通信就是通过端口,端口是什么定义呢?
端口是这些设备和cpu连接的接口芯片。
1.这些芯片中都有一组可以由cpu读写的寄存器。
这些芯片都是和总线相连接。
2.这些芯片当cpu对他们读写的时候都是通过控制线向他们所在的芯片端口发出端口读写命令的,然后由端口读写进对应的设备


端口地址才相当于你说的外设的单元号.比如 IN AL, 60H ;从端口60H读入一个字节到AL中 这个60H相当于地址.
至于你说的地址怎么换算就是计算机组成原理的内容了.关于外设有2种寻址方式,每个连接到I/O总线上的设备都
有自己的I/O地址集,即所谓的I/O端口(I/O port)。在IBM PC体系结构中,I/O地址空间一共提供了65,536个
8位的I/O端口。可以把两个连续的8位端口看成一个16位端口,但是这必须是从偶数地址开始。同理,也可以把
两个连续的16位端口看成一个32位端口,但是这必须是从4的整数倍地址开始。有四条专用的汇编语言指令可以
允许CPU对I/O端口进行读写:它们分别是in、ins、out和outs。在执行其中的一条指令时,CPU使用地址总线
选择所请求的I/O端口,使用数据总线在CPU寄存器和端口之间传送数据。   I/O端口还可以被映射到物理地
址空间:因此,处理器和I/O设备之间的通信就可以直接使用对内存进行操作的汇编语言指令
(例如,mov、and、or等等)。现代的硬件设备更倾向于映射I/O,因为这样处理的速度较快,
并可以和DMA结合起来使用。也就解释了为什么32位系统名义上支持4G内存,实际上你装上4G
内存条在机器上是不行了。因为访问不到4G,还需要为显卡,声卡等设备提供物理地址的映射。

系统设计者的主要目的是提供对I/O编程的统一方法,但又不牺牲性能。为了达到这个目的,
每个设备的I/O 端口都被组织成一组专用寄存器。CPU把要发给设备的命令写入控制寄存器
(control register),并从状态寄存器(status register)中读出表示设备内部状态的值。
CPU还可以通过读取输入寄存器(input register)的内容从设备取得数据,也可以通过向
输出寄存器(output register)中写入字节而把数据输出到设备。

DMA 传输将数据从一个地址空间复制到另外一个地址空间。当CPU 初始化这个传输动作,
传输动作本身是由 DMA 控制器来实行和完成。
典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。
像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。
DMA 传输对于高效能 嵌入式系统算法和网络是很重要的。


在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。一个完整的DMA传输过程必须经过DMA请求、DMA响应、DMA传输、DMA结束4个步骤。
Parity
cmp配合条件跳转指令一起使用,cmp表示比较,但是表


汇编的原码补码反码:
原码是将进制转换成二进制,10000001
反码 是将符号位保持不变,其他位置相反 11111110
补码: 如果是正数,则补码是其本身,如果是负数,补码=反码+1    11111110+1=1111111
为什么需要补码反码??
对于计算机,加减乘除已经是最基础的运算,要设计的尽量简单,计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂。。所以人们想到,将符号位也参数运算的方法
。我们知道跟军运算法则减去一个正数等于加上一个负数。所以机器可以只有加法而没有减法。这样计算机运算的设计就更简单了。
一正一负相加:
计算十进制的表达式: 1-1=0

    1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
计算十进制的表达式: 1-1=0

    1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

于是补码的出现, 解决了0的符号以及两个编码的问题:

    1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
这个例子我们知道计算机是根据补码运算的。因为反码无法进行
两个正数相加:
1+1
00000001+00000001=00000010   =2 


ret 和retf  
ret用栈中的数据修改ip指令的地址,从而实现近转移 
retf 用栈中的数据修改cs:ip的地址,从而实现远转移

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值