随笔分类 -  汇编语言

摘要:assume cs:code,ds:data,es:info_numdata segment db '11/11/11 11:11:11$' ;预设字符串data endsinfo_num segment db 9,8,7,4,2,0 ;端口时间地址列表info_num endscode segmentstart: mov ax,data mov ds,ax mov si,0 ;初始指向字符串首 mov ax,info_num mov es,ax mov bp,0 ;指向端口时间地址列表首 ... 阅读全文
posted @ 2013-09-09 10:30 tsembrace 阅读(1250) 评论(0) 推荐(1) 编辑
摘要:这篇是自己去年学习时候写的,重新放出来,可以和现在的对比一下:实验要求:编程:以“年/月/日 时:分:秒”的格式显示出当前的日期、时间。准备工作:因为CMOS9号单元存储的是年份数据,那么该数据对应的是两位的十进制数字,拿今年2011年来说,9号单元里存储的就应该是BCD码:00010001.为了验证一下,同时也巩固下CMOS的读写操作,做了一个小程序,如下:-----------------------------------assume cs:codecode segmentstart: mov al,9 out 70h,al in al,71h mov bl,al mov al,8 ou 阅读全文
posted @ 2013-09-09 10:28 tsembrace 阅读(959) 评论(0) 推荐(0) 编辑
摘要:第十四章 端口*PC机中,和CPU通过总线相连的芯片除了各种寄存器外,还有以下三种芯片:1、各种接口卡(如网卡、显卡)上的接口芯片,他们控制接口卡进行工作;2、主板上的接口芯片,CPU通过他们对部分外设进行访问;3、其他芯片,用来存储相关系统信息,或进行相关的输入输出处理。上述三种芯片都有一组供CPU读写的寄存器,物理上可能处于不同的芯片中,但均具备以下特点:1、所在的芯片与CPU通过总线相连;2、CPU对这些芯片进行读写操作时都通过控制线向其所在的芯片发出端口读写指令;3、从CPU的角度,讲这些寄存器都当做端口,并对他们进行统一编址,建立统一的端口地址空间,每个端口在地址空间中均有一个地址。 阅读全文
posted @ 2013-09-09 09:39 tsembrace 阅读(310) 评论(0) 推荐(0) 编辑
摘要:本章在用int 7ch实现loop指令功能时候,所用的参数为cx:循环次数,bx:loop指令的转移位移值。cx的值可以在调用程序里给出,而bx的值却需要用表达式表示,同时为了可以表达,也需要在中断调用指令后加一个无实际含义的"s1:nop"之类的指令,以使得可以将bx表达为"offset s-offset s1"。其实,通过int 7ch实现loop的要点在于在循环未结束(即cx!=0)时将ip指向跳转目的偏移地址,即s处。因此,设置入口参数为bx=offset s.;中断例程安装程序二assume cs:code code segment start 阅读全文
posted @ 2013-09-08 20:26 tsembrace 阅读(617) 评论(0) 推荐(0) 编辑
摘要:第十三章 int指令*int n引发n号中断过程,执行过程如下:(1)取得中断类型码n(2)pushf,TF=0,IF=0(3)push cs,push ip(4)(cs)=(0000:(4n+2)),(ip)=(0000:(4n))*用int 7ch实现loop指令功能的分析(1)loop实现的是指令跳转,属于短转移,即位移量在-128~127之间;同时,需要获得cx以确定循环次数;通过判断cx是否为0来决定是否执行跳转。(2)cx值可从调用程序中获得;7ch中断例程依据判断cx=0?来确定跳转,可以想到用jmp指令实现(?未深入细想)或者按书上用iret,修改栈顶元素的值,使其指向跳转目的 阅读全文
posted @ 2013-09-08 19:34 tsembrace 阅读(343) 评论(0) 推荐(0) 编辑
摘要:assume cs:code code segment start:;do0安装程序----------------- mov ax,code mov ds,ax mov si,offset do0 mov ax,0000 mov es,ax mov di,0200h CLD mov cx,offset do0end-offset do0 rep movsb;do0安装结束-----------------;设置0号中断程序入口--------- mov ax,0 mov es,ax mov word ptr es:[0000],200h mov ax,0000h mov word ptr e 阅读全文
posted @ 2013-09-06 16:37 tsembrace 阅读(470) 评论(0) 推荐(0) 编辑
摘要:第十二章 内中断*四种引发内中断的情况(1)除法错误,如溢出;对应中断类型码0(2)单步执行;对应中断类型码1(3)into指令;对应中断类型码4(4)int N;对应中断类型码N*中断向量表当引发内中断时候,cpu转入执行相应中断程序,而各类中断类型码对应的中断程序固化存于内存中;这就需要通过不同的中断类型码以获取其对应的中断程序的入口地址,即有了中断向量表。中断向量表固化于0000:0000~03ffh内存段中;中断类型码n:对应中断程序的入口地址为:段地址0000:(4n+2),偏移地址0000:(4n).*中断过程-----中断开始------(1)响应中断,取得中断类型码n(2)pu 阅读全文
posted @ 2013-09-06 16:02 tsembrace 阅读(554) 评论(0) 推荐(0) 编辑
摘要:assume cs:codedata segment db "Beginner's All-purpose Symbolic Instruction Code.",0data endscode segmentbegin: mov ax,data mov ds,ax mov si,0 call letterc mov ax,4c00h int 21h;名称:letterc;功能:将以0结尾的字符串中的小写字母转变为大写字母;参数:ds:si指向字符串首地址letterc: push cx pushf mov cx,0s1: mov... 阅读全文
posted @ 2013-08-30 16:03 tsembrace 阅读(1923) 评论(0) 推荐(1) 编辑
摘要:汇编语言---关于自定义的段占用内存空间在王爽汇编实验5(2)中有这样一个问题:对于如下定义的段:name segment ...name ends如果段中的数据占N个字节,则程序加载后,其实际占用空间当时在做这道题时候,只是通过debug加载多个类似程序,然后观察,得出实际占用空间为16;([N/16]+1)字节。即对于设定的段空间,如果在预设时候的数据不足16字节;则给其分配空间为m{m=([N/16]+1)},编译器会自动给其增补内存空间。当时只是以为这就是规则,而没有深入去考虑为什么制定这样的规则?对于程序而言,数据段的设置是为了方便使用,而使用数据段则需要知道其段地址。举例如下:a 阅读全文
posted @ 2013-08-30 14:14 tsembrace 阅读(2970) 评论(0) 推荐(0) 编辑
摘要:第十一章 标志寄存器一、各标志位说明1、ZF标志*名称:零标志位*位置:第6位*作用:记录相关指令执行后,结果是否为0.如果结果为0,则zf位为1;反之为0.2、PF标志*名称:奇偶标志位*位置:第2位*作用:记录相关指令执行后,结果所有bit位中为1的个数是否为偶数.如果为偶数,则pf位为1;反之为0.3、SF标志*名称:符号标志位*位置:第7位*作用:记录相关指令执行后,结果是否为负.若为负,则sf位为1;反之为0。4、CF标志*名称:进位标志位*位置:第0位*作用:记录相关指令执行后,结果是否向更高位借位(进位)。若有借位(进位),则cf位为1;反之为0.*备注:只相关于无符号数的运算。 阅读全文
posted @ 2013-08-30 14:10 tsembrace 阅读(844) 评论(0) 推荐(0) 编辑
摘要:;程序目标为在屏幕指定位置显示数据;数据分为四项:年份、收入、员工数、人均收入;其中人均收入要通过计算得出;上述数据又分为两大类:字符类:如年份;数字类:(收入、员工数、人均收入);字符类不需要转换可直接存入显示缓冲区;数字类需要先转换为对应字符,再存入显示缓冲区;程序设计思路如下:;第一步:求出人均收入存入data指定区域(设计子函数1:避免溢出的dword/word型运算);第二步:在指定区域显示年份数据(设计子函数2:显示指定内存区的数据到屏幕指定位置);第三步:将指定区域dword型数字数据转换成字符串并显示(设计子函数3:转换dword型数据为字符串,存入指定显示缓冲区);第四步:将 阅读全文
posted @ 2013-08-28 16:34 tsembrace 阅读(2194) 评论(1) 推荐(1) 编辑
摘要:第十章 CALL和RET指令一、ret和retf*ret:功能为:pop ip,实现的是段内近转移;相当于jmp near ptr X*retf功能为:pop ip,pop cs,实现的是远转移;相当于jmp far ptr X二、call指令*call指令分为两步:(1)将当前IP压入栈;(2)设置新IP进行转移。1、依据位移进行转移的call指令call 标号,功能为:push IPjmp near ptr 标号可看出call的转移操作与jmp near ptr一样,均使用位移进行,位移量为16位。2、直接使用转移目的地址的call指令(1)转移目的地址在指令中的call指令:call f 阅读全文
posted @ 2013-08-26 16:33 tsembrace 阅读(1219) 评论(0) 推荐(0) 编辑
摘要:一、编程目标:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。二、程序分析在屏幕中显示字符即是向显示缓冲区的对应区域写入字符。1、定位屏幕输出位置字符串长度为16,屏幕每行总共为80个字符的输出宽度。要使得居中,则字符左右要各空32个字符位置。即字符串首字符位于每行的第33个字符位,字符串占第33列到第48列。屏幕每页为25行,输出目标为3行,即三个字符串占第12、13、15行。即第一个字符串在显示缓冲区内起始位置为:(B8000H+11*80*2+32*2);第二行的起始地址为在第一行基础上加上80*2;第三行类推。2、字符信息的设置字 阅读全文
posted @ 2013-08-25 18:55 tsembrace 阅读(1703) 评论(0) 推荐(1) 编辑
摘要:第9章 转移指令的原理一、8086转移指令的分类1、无条件转移指令,如jmp;2、条件转移指令,如jcxz;3、循环指令,如loop;4、过程;5、中断二、几种转移指令的详解*基础知识:补码在计算机系统中,数值一律用补码来表示(存储)。正数补码与原码相同,如十进制17;原码为0001 0001;其补码也为0001 0001;负数的补码最高位取1,剩余7位为将负数取绝对值按位取反后+1,得其补码(对8位补码)。如-1;最高位取1,绝对值7位为0000001,按位取反后为1111110;+1后为1111111;则-1的补码为11111111.也可知,对8位补码,其可表示的数值范围为-128~127 阅读全文
posted @ 2013-08-25 16:53 tsembrace 阅读(2513) 评论(2) 推荐(0) 编辑
摘要:第八章 数据处理的两个基本问题一、寄存器*reg:表示寄存器。8086寄存器包括ax,bx,cx,dx,al,ah,bl,bh,cl,ch,dl,dh,ss,cs,es,ds,sp,bp,si,di;其中sreg表示段寄存器,包括ds,es,ss,cs.*只有bx,bp,si,di这四个寄存器可用来作为偏移地址寻址。且bx和bp不能同时使用,si和di不能同时使用,具体应用方式如下: [bx],[bp],[si],[di];[bx+si],[bx+di],[bp+si],[bp+di];[bx+si+idata],[bp+di+idata]..etc.*对于使用bx寻址的应用,段地址默认存在d 阅读全文
posted @ 2013-08-25 15:14 tsembrace 阅读(1558) 评论(0) 推荐(1) 编辑
摘要:第七章 更灵活的定位内存地址的方法7.1 and和or指令(1)and/or指令:按位的运算符。不能对内存单元直接操作,须借助寄存器中转。(2)and/or指令的应用:因为不管1还是0,和1进行与运算,都能维持原数不变;与1进行或运算,都能使原数置1.和0进行与运算,都能置0;和0进行或运算,都能维持原数不变。可利用上述特点,进行一些应用,比如转换大小写字母。一个字母的大写ASCII码都比小写ASCII码值小20H。比如A是41H,a是61H。对应二进制码分别为0100 0001H,0110 0001H.如果要将A转成a,直接用A+20H就可以。但如果有一个字母,事先不知道其是大写还是小写,但 阅读全文
posted @ 2013-08-18 16:44 tsembrace 阅读(4959) 评论(3) 推荐(1) 编辑
摘要:在学习王爽汇编第六章的时候,接触到在源程序中不同段的设置,如数据段、栈段、代码段的分别设置。如下格式:assume cs:code,ds:data,ss:stackdata segment ...data endsstack segment ...stack endscode segmentstart: ...code endsend start那么对于data段定义的数据来说,定义后CPU给这段数据的空间大小是如何确定的呢?通过第六章的实验题目,可以知道:数据段空间大小为定义数据所需的16字节的最小整数倍。比如定义了1个字节,系统就给数据段分配16个字节;定义了17个字节,系... 阅读全文
posted @ 2013-08-18 11:50 tsembrace 阅读(13813) 评论(0) 推荐(2) 编辑
摘要:检测点6.1(1)依次用内存0:0~15单元中的内容改写程序中的数据,补全程序:assume cs:codesgcode segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hstart: mov ax,0 mov ds,ax mov bx,0 mov cx,8s: mov ax,[bx] mov cs:[bx],ax ;确定目标区域段地址和偏移地址 add bx,2 loop s mov ax,4c00h int 21hcodesg endsend star... 阅读全文
posted @ 2013-08-17 16:03 tsembrace 阅读(24352) 评论(6) 推荐(2) 编辑
摘要:(1)编程,向内存0:200~0:23f依次传送数据0~63.assume cs:codecode segment mov ax,20H mov ds,ax mov bx,0 mov cx,64s: mov [bx],bl inc bx loop s mov ax,4c00H int 21Hcode endsend(3)程序功能是将"mov ax,4c00h"之前的指令复制到内存0:200处,补全程序:;只写关键代码;每次复制单字节数据,并通过al中转;程序入口为cs:0(ip=0),所以第一空处传递段地址为cs;接下来需要确定循环次数,即... 阅读全文
posted @ 2013-08-11 18:56 tsembrace 阅读(18482) 评论(1) 推荐(0) 编辑
摘要:第五章 [BX]和loop指令*Loop指令格式:loop 标号等同步骤:(1)(cx)=(cx)-1;(2)若(cx)!=0,跳转到标号位置继续执行。*Debug的相关命令及说明g命令:g 偏移地址;使得执行到cs:偏移地址处停止;p命令:使Debug程序自动重复执行代码中的循环指令,直到(cx)=0为止。用Debug中直接写入指令,[idata]可以表示((段地址)*16+idata)处的值;而如果在汇编源代码中[idata]会被编译器masm处理为idata这个数值。所以在汇编源代码中当使用立即数来表示偏移地址时,须加前缀以显式表明,比如:ds:[idata]。*示例:计算ffff:0~ 阅读全文
posted @ 2013-08-11 18:36 tsembrace 阅读(784) 评论(0) 推荐(0) 编辑