汇编语言--寄存器(内存访问)

本文主要从CPU如何执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、相关的寄存器以及一些指令

本文地址:http://www.cnblogs.com/archimedes/p/assembly-register-memory.html,转载请注明源地址。

内存中字的存储

在cpu中,用16位来存储一个字,高8位存放高字节,低8位存放低位字节。在内存中时,由于内存单元是字节单元,刚一个字要用2个地址连续的内存单元来存放,字的低位字节存在低地址单元.

字单元--存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成,高地址内存单元中存放字型数据的高字节,低地址内存单元存放单元中存放字型数据的低位字节

0地址单元中存放的字节型数据为20H,0地址单元中存放的字型数据为4E20H,2地址单元中存放的字节型数据为12H,2地址单元中存放的字型数据为0012H,

DS和[address]

8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。比如我们要读取10000H单元的内容,可以用如下的程序段进行:

mov bx,1000H
mov ds,bx
mov al,[0]

[……]表示一个内存单元,0表示内存单元的偏移地址

字的传送

8086CPU是16位结构,可以一次性的传送16位的数据,即一次性传送一个字。例如:

mov bx,1000H
mov ds,bx
mov ax,[0]  ;1000:0处的字型数据送入ax
mov [0],cx  ;cx中的16位数据送到1000:0

问题1

内存中的情况如下图,

写出下面指令执行后寄存器ax,bx,cx中的值

mov ax,1000H
mov ds,ax
mov ax,[0]
mov bx,[2]
mov cx,[1]
add bx,[1]
add cx,[2]

mov ax,1000H 执行后,ax=1000H

mov ds,ax 执行后,ds=1000H

mov ax,[0] 执行后,ax=1123H

mov bx,[2] 执行后,bx=6622H

mov cx,[1] 执行后,cx=2211H

add bx,[1] 执行后,bx=bx+[1]=6622H+2211H=8833H

add cx,[2] 执行后,cx=6622H+2211H=8833H

问题2

内存中的情况如下图,

写出下面指令执行后寄存器ax,bx,cx中的值

mov ax,1000H
mov ds,ax
mov ax,11316
mov [0],ax
mov bx,[0]
sub bx,[2]
mov [2],bx

mov ax,1000H 执行后,ax=1000H

mov ds,ax 执行后,ds=1000H

mov ax,11316 执行后,ax=2C34H

mov [0],ax 执行后,1000:1存储2C,1000:0存储34

mov bx,[0] 执行后,bx=2C34

sub bx,[2] 执行后,bx=2C34-1122=1B12

mov [2],bx 执行后,1000:2存储1B12

指令执行结果如下:

mov、add、sub指令

mov指令有以下几种形式:

mov 寄存器,数据

mov 寄存器,寄存器

mov 寄存器,内存单元

mov 内存单元,寄存器

mov 内存单元,段寄存器

mov 段寄存器,寄存器

mov 寄存器,段寄存器

下面通过debug来验证一下"mov 寄存器,段寄存器"指令:

验证"mov 内存单元,段寄存器"指令:

mov ax,1000H
mov ds,ax
mov [0],cs

add和sub指令同mov一样,都有两个操作对象,也可以有下面几种形式:

add 寄存器,数据

add 寄存器,寄存器

add 寄存器,内存单元

add 内存单元,寄存器

sub 寄存器,数据

sub 寄存器,寄存器

sub 寄存器,内存单元

sub 内存单元,寄存器

数据段

相关结论:

1、字在内存中存储时,要用两个连续的内存单元来存放,字的低字节放在低地址单元,高字节放在高地址单元

2、用mov指令访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中

3、[address]表示一个偏移地址为address的内存单元

4、在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应

5、mov、sub、add是具有两个操作对象的指令,jmp是具有一个操作对象的指令

CPU提供的栈机制

在8086CPU编程的时候,可以将一段内存当做栈来使用,8086CPU提供2种栈的操作:push和pop,都是以字为单位进行操作

在8086CPU中,提供2中寄存器分别栈顶地址:段寄存器SS和寄存器SP,任意时刻,SS:SP指向栈顶元素。入栈时,栈顶从高地址向低地址方向增长

首先看一段代码:

mov ax, 0123H
push ax
mov bx, 2266H
push bx
mov cx, 1122H
push cx
pop ax
pop bx
pop cx

执行过程如下图:

注意:字型数据用两个单元存放,高地址单元存放高8位,低地址单元存放低8位

8086CPU中,有2个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素

8086CPU不保证我们对栈的操作不会超界,我们在编程的时候要自己操心栈顶超界的问题

push、pop指令

push和pop指令是可以在寄存器和内存之间传送数据的,push和pop指令可以是如下的形式:

push 寄存器 ;将一个寄存器中的数据入栈

pop 寄存器 ;出栈,用一个寄存器接收出栈的数据

push 段寄存器 ;将一个段寄存器中的数据入栈

pop 段寄存器 ;出栈,用一个段寄存器接收出栈的数据

;push和pop指令也可以在内存单元和内存单元之间传送数据,还可以:

push 内存单元 ;将一个内存单元处的字入栈(栈的操作都是以字为单位)

pop 内存单元 ;出栈,用一个内存字单元接收出栈的数据

比如下面的代码:

mov ax, 1000H
mov ds, ax ;内存单元的段地址要放在ds中
push [0] ;将1000:0处的字入栈中
pop [2]  ;出栈,出栈的数据送入1000:2处

参考资料

《汇编语言》--王爽

时间: 2024-12-30 09:54:20

汇编语言--寄存器(内存访问)的相关文章

3.寄存器(内存访问)

寄存器(内存访问) 看到标题才发现,第二章是寄存器直接与常量(数字)进行交互 内存中字的存储假设读取字节(流)为从左向右读对字的处理为从又向左正是因为不同,所以才会发问吧 DS与偏移地址:通用的获取地址的方式(CS:IP这个是给程序用的)类似于通用寄存器,但不能使用move ds,1:单纯的说指令太少了的话也对(jmp 不也就省2指令,还多出N多种),应该是跟指令流程相关(intel 指令手册,我的第一反应其实是是使用灵活的方式进行修改还是使用通用的方式进行修改...小学语文学太多了,自动升华)

汇编语言:第三章 寄存器(内存访问)

3.1内存中字的存储 CPU中寄存器是16位的,可以用高低字节存储一个字,但是每个内存单元是8位的,只能存储一个字节, 所以内存中用相邻2个内存单元存储一个字的高低字节 如:20000数值(4E20H)在地址0的内存单元数值为20H,在地址1的内存单元数值为4EH 两个内存单元存储一个字型数据叫做一个字单元, 字单元的起始地址为N就叫N地址字单元,表示一个字的低字节在地址N的内存单元,高字节在地址N+1的内存单元 任意连续的2个内存单元都可以组成一个字单元 3.2 DS和 [address] C

汇编学习笔记03(寄存器内存访问)

1. 字在内存中存储时, 要有两个地址连续的内存单元来存放. 字的低位字节存放在低地址单元中, 高位字节存放在高地址单元中. 2. DS: 存放段地址的寄存器, 这个段是存放数据的. [address]: 偏移地址 mov指令在访问内存单元时, 只给出偏移地址, 段地址默认在DS段寄存器中 3. mov ax, 1000 mov ds, ax 8086CPU不支持将数据直接送入段寄存器, 所以只能通过通用寄存器来进行中转. 4. 字的传送 80806CPU是16位结构, 有16根数据线, 所以一

寄存器(内存访问)

1.内存访问 CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086CPU中,内存地址由段地址和偏移地址组成.8086中有一个DS寄存器,通常用来存放要访问数据的段地址.例如我们要读取10000H单元的内容,可以用如下的程序段进行. mov bx,1000H mov ds,bx mov al,[0] [...]表示一个内存单元,其中的0表示内存单元的偏移地址.段地址从ds中获取. 8086CPU不支持将数据直接送入段寄存器的操作,所以使用寄存器bx作个中转. 2.几个指令 mo

汇编语言(王爽) 第3章寄存器(内存访问)

3.1 内存中的字 内存中的字是16位的,以2个内存单元存储 地址大的存高位(字的左边8位),地址小的存低位(字的右边8位) 字单元:存放1个字形数据的内存单元,由2个内存单元组成,共16位 3.2 DS 一个寄存器的名字,用来放数据段的段地址 mov 指令可以把数据转到寄存器,一个寄存器的内容转到另一个寄存器,内存单元(字单元)转到寄存器 但是一般会mov ax,1000h;mov ds,ax而不是直接mov ds,1000h 因为8086CPU不支持直接把内存单元的东西转到段寄存器上面 3.

汇编入门学习笔记 (二)—— 寄存器(内存访问)、栈

疯狂的暑假学习之  汇编入门学习笔记 (二) 参考:<汇编语言> 王爽  第三章 一.寄存器(内存访问) 1.DS和[address] DS 数据段寄存器,用来存放数据段地址 [address] 用来表示数据段的偏移地址 同样跟CS一样,不可以通过 mov ds, 1000 给ds赋值 要通过通用寄存器ax等. 例如: mov ax, 1000 mov ds, ax mov al, [0] 把1000:0的内容存进al mov bx, 1000 mov ds, bx mov [0], al 把

汇编学习笔记--寄存器(内存访问 1)

内存访问首先要有地址,8086pc中的段地址存放在 ds 寄存器中(ds 和 cs是不一样的,cs是定位地址用于读取内存中的指令或者数据,而ds是读取内存中的数据时使用,下面我们会明白区别) 将内存中的数据写入寄存器: mov bx,1000H mov ds,bx mov al,[0] 第一句是把1000H给bx(寄存器),第二句把bx中的值给ds(段地址寄存器),第三句从1000:0H中读取数据给al(寄存器ax的低8位):至于为什么不直接把段地址1000H给ds,这是8086硬件设计的问题,

第三章 寄存器(内存访问)

在第五章的学习之后,因为实验课在老师的抽查之后发现前面的知识很多都忘了,便对之前的知识进行了一遍系统的复习,对汇编的基础知识基本都已经掌握,也有了更加深刻的认识. 在第三章中我们主要从内存访问的角度来继续学习CPU执行指令的原理,并进一步的学习上一章的寄存器. <1>内存中字的存储 字由高位字节和低位字节组成,用16位寄存器来存储.高八位存放高位字节,低八位存放低位字节.字需要两个地址连续的内存单元(一个字节)来存储,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中.如下图,我们想要

汇编语言 使用内存空间

汇编语言 使用内存空间 在上一个实验我们已经知道,c语言使用寄存器需要我们给出相应寄存器的名称,在函数执行过程中就能一一对应. 下面,我们来研究c语言如何使用内存空间: 我们已经知道像偏移地址2000h中写入一个字节的内容,我们用如下方法: *(char *)0x2000='a'; 像2000:0写入一个字节用如下方法: *(char far *)0x20000000='a'; 有了上面两点知识下面进行试验: 1.编写一个程序um1.c 编译.链接生成.exe文件,然后用debug加载,对mai

GNU C - 关于8086的内存访问机制以及内存对齐(memory alignment)

一.为什么需要内存对齐? 无论做什么事情,我都习惯性的问自己:为什么我要去做这件事情? 是啊,这可能也是个大家都会去想的问题, 因为我们都不能稀里糊涂的或者.那为什么需要内存对齐呢?这要从cpu的内存访问机制说起. 为了了解清楚cpu的内存访问机制,昨天整晚都在查找资料,但是还是找不到很好的介绍资料.后来只是找到了相关 的一些介绍的博客. 这些博客中大多都是以介绍内存对齐为主要目的,然后顺带着说一下cpu的内存访问机制,所以 找不到权威的资料,后来听说<<汇编语言编程艺术>>这本书