汇编语言feibilun

8086CPU有四个段寄存器:CS,DS,SS,ES段寄存器用来提供段地址

CS:代码段寄存器IP:指令指针寄存器修改CS,IP:jmp段地址:偏移地址仅修改IP的内容:jmp某一合法寄存器jmpax用ax中的值修改IP下面的3条指令执行后,cpu几次修改IP?都是在什么时候?最后IP中的值是多少?

movax,bx

subax,ax

jmpax

答:一共修改四次

第一次:读取movax,bx之后

第二次:读取subax,ax之后

第三次:读取jmpax之后

第四次:执行jmpax修改IP

最后IP的值为0000H,因为最后ax中的值为0000H,所以IP中的值也为0000H

-r:查看寄存器内容-rax:修改ax的内容-t:执行指令-d:查看内存中内容-u:查看内存中内容,将机器指令翻译成汇编指令-e:改写内存中内容(机器指令)-a:以汇编指令的格式在内存中写入一条机器指令

DS寄存器通常用来存放要访问的数据的段地址若要读区10000H单元内容到寄存器:

movbx,1000Hmovds,bxmoval,[0]不可以直接movds,1000H8086cpu不支持直接将数据送入段寄存器

将al中数据送入内存单元10000H:

movbx,1000Hmovds,bxmov[0],al8086cpu有16根数据线,一次性可以传一个字movmov段寄存器,寄存器是可以的但是mov寄存器,段寄存器可以吗?答案是可以。

段寄存器SS:存放栈顶的段地址寄存器SP:存放栈顶的偏移地址任意时刻,SS:SP指向栈顶元素

movax,1000Hmovss,ax//不能直接mov数据到段寄存器movsp,0010Hpushaxpushbxpushds第一个程序!assumecs:abcabcsegment movax,2 addax,ax addax,ax movax,4c00H int21Habcendsend.asm源代码文件,masm后.obj,link后.exe可以加一个入口,然后debug,debug.exe要放在文件夹中。

若源程序中这样写movax,[0]编译器会认为是movax,0所以要这样:movax,[bx]bx中放偏移地址。在debug中可以movax,[0]

执行loop时

movcx,11s:addax,axloops以上代码共执行11次add。注意:在汇编源程序中数据不能以字母开头!所以movax,0ffffhdebug时用g命令可以直接跳到想要跳到的ip处。-g000B也可以在ip在loop那行时执行p命令。

在一般的PC机中,DOS方式下,DOS和其他合法程序一般都不会用0:200h-0:2ffh的256个字节的空间,所以我们使用这段空间是安全的。把ffff:0-ffff:b中的数据放入0020:0-0020:b中:

assumecs:codecodesegment movax,0ffffH movds,ax movax,0020H moves,ax movbx,0 movcx,12s: movdl,[bx] moves:[bx],dl incbx loops movax,4c00H int21Hcodeendsend使用es存目标段地址,避免在循环中重复改变ds

dw:defineword

assumecs:codecodesegment dw1h,2h,3h,4h movbx,0 movax,0 movcx,4s:addax,cs:[bx] addbx,2 loops movax,4c00h int21hcodeendsend1h在cs:0处,依次放4个字这样的话cpu会把这些字转换成指令,而这些并不是指令,cpu会误读指令,我们可以在第一条需要执行的代码前加start(或其他任意,只要和end后对应):

assumecs:codecodesegment dw1h,2h,3h,4hstart: movbx,0 movax,0 movcx,4s:addax,cs:[bx] addbx,2 loops movax,4c00h int21hcodeendsendstartend除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。

利用栈,将程序中定义的数据逆序存放

assumecs:codesgcodesgsegment dw0123h,0456h,8976h,0987h,4576h,0345h,0984h,7678h dw0,0,0,0,0,0,0,0;用dw定义8个字型数据,程序加载后将取得8个字的内存空间,后面把这些空间当作栈来使用。start:movax,cs movss,ax movsp,32 movbx,0 movcx,8s: pushcs:[bx] addbx,2 loops movbx,0 movcx,8s1:popcs:[bx] addbx,2 loops1 movax,4c00h int21hcodesgendsendstart将数据,代码,栈放入不同的段assumecs:codesg,ds:data,ss:stackdatasegment dw0123h,0456h,8976h,0987h,4576h,0345h,0984h,7678hdataendsstacksegment dw0,0,0,0,0,0,0,0stackendscodesgsegmentstart:movax,stack movss,ax movsp,16 movax,data movds,ax movcx,8 movbx,0s: push[bx] addbx,2 loops movcx,8 movbx,0s1:pop[bx] addbx,2 loops1 movax,4c00h int21hcodesgendsendstart不可以movds,data对于如下定义的段namesegment...nameends如果段中的数据占N个字节,程序加载后,该段实际占有的空间为16*(N/6+1)用push指令将a段中的前8个字型数据逆序存放到b段中:

assumecs:codeasegment dw1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffhaendsbsegment dw0,0,0,0,0,0,0,0bendscodesegmentstart: movax,a movds,ax movax,b movss,ax movsp,16 movbx,0 movcx,8s: push[bx] addbx,2 loops movax,4c00h int21hcodeendsendstart更灵活的定位内存地址大小写转换:小写字母的ASCII码比对应的大写字母大32,即100000B.大写->小写,oral,00100000B;小写->大写,andal,11011111B

assumecs:code,ds:datadatasegment db'BaSiC' db'iNfOrMaTiOn'dataendscodesegmentstart: movax,data movds,ax movbx,0 movcx,5 s:moval,[bx]andal,11011111B mov[bx],al;小写to大写 incbx loops movbx,5 movcx,11s1:moval,[bx]oral,00100000B mov[bx],al;大写to小写 incbx loops1 movax,4c00H int21Hcodeendsendstart[bx+idata]作为偏移地址movax,[bx+5]movax,[5+bx]movax,5[bx]movax,[bx].5

assumecs:code,ds:datadatasegment db'BaSiC';转换为大写 db'iNfOr';转换为小写dataendscodesegmentstart: movax,data movds,ax movbx,0 movcx,5 s:moval,[0+bx] andal,11011111b mov[0+bx],al moval,[5+bx] oral,00100000b mov[5+bx],al incbx loops movax,4c00H int21HcodeendsendstartSI和DISI和DI不能分成两个8位寄存器使用。

movsi,0movax,[si]movdi,0movax,[di]movdi,0movax,[di+123]assumecs:code,ds:datadatasegment db'welcometomasm!' db'................'dataendscodesegmentstart: movax,data movds,ax movsi,0 movcx,16 s:moval,[si] mov[16+si],al incsi loops movax,4c00h int21hcodeendsendstart[bx+si],[bx+di][bx+si+idata],[bx+di+idata]练习:

assumecs:codesg,ds:datasgdatasgsegment db'abc' db'def' db'ghi' db'gkl'datasgendscodesgsegmentstart: movax,datasg movds,ax movbx,0 movcx,4 s:movdx,cx movcx,3 movdi,0 s1: moval,[bx+di] andal,11011111b mov[bx+di],al incdi loops1 addbx,16 movcx,dx loops movax,4c00h int21hcodesgendsendstart但是用dx暂存cx不合适,dx有可能会用到。使用栈:

movwordptrds:[0],1incwordptr[bx]incwordptrds:[0]addwordptr[bx],2若是字节型,byteptrpush只push字型数据pushds:[1]

计算100001/100100001=186a1h

movdx,1hmovax,86a1hmovbx,100divbx执行完成后,(ax)=03e8h(100),(dx)=1计算1001/100

movax,1001movbl,100divbl执行后,(al)=0ah,(ah)=1

用来定义doubleword,32位

assumecs:code,ds:datadatasegment dd100001 dw100 dw0dataendscodesegmentstart:movax,data movds,ax movax,ds:[0] movdx,ds:[2] movbx,ds:[4] divbx movds:[6],ax movax,4c00h int21hcodeendsendstart伪指令dup和db,dw,dd配合使用,进行数据的重复。

assumecs:codecodesegmentstart:movax,offsetstart;相当于movax,0s:movax,offsets;相当于movax,3codeendsendstart把s处的第一条指令复制到s0处:

assumecs:codecodesegments: movax,bx;2bytes movsi,offsets movdi,offsets0 movax,cs:[si] movcs:[di],axs0:nop;1byte nopcodeendsendjmp指令无条件跳转

movax,0123hmovds:[0],axjmpwordptrds:[0]跳转到ip0123h处jmpdwordptr内存单元地址(cs)=(内存单元地址+2)(ip)=(内存单元地址)movax,0123hmovds:[0],axmovwordptrds:[2],0jmpdwordptrds:[0](cs)=0,(ip)=0123hjcxz指令有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对ip的修改范围都为-128~127格式:jcxz标号当(cx)=0时,(IP)=(IP)+8位位移当(cx)!=0时,程序向下执行

短转移,在对应的机器码中包含转移的位移,而不是目的地址。对ip的修改范围-128~127

jmpshort标号jmpnearptr标号jcxz标号loop标号在他们的机器码中不包含转移的目的地址,包含的是到目的地址的位移距离。转移范围有限,超出编译时编译器将报错。

注意:jmp2000:1000这样的转移指令实在debug中使用的,汇编编译器并不认识。

实验8:

ret指令用栈中的数据,修改ip的内容,从而实现近转移。cpu执行ret指令时,进行下面两步操作:

cpu执行call指令,进行两步操作:

call不能实现短转移,除此之外,call实现转移的方法和jmp指令的原理相同。

call16位寄存器功能:ip入栈,跳到ip为寄存器内容处

转移地址在内存中

callwordptr内存单元地址段内先puship再跳到内存中存着的ip

calldwordptr内存单元地址先pushcs,puship,再跳内存中第一个字存着要跳的ip,下一个字存着要跳的cs

movsp,10hmovax,0123hmovds:[0],axmovwordptrds:[2],0calldwordptrds:[0]执行后,(cs)=0,(ip)=0123h,(sp)=0ch

mulregmul内存单元用al或者ax中的数据×,都是8位或者都是16位。8位的两个数结果存在ax,16位的两个数结果高位存在DX,低位存在AX计算100*10:

moval,100movbl,10mulbl结果(ax)=1000计算100*10000:

movax,100movbx,10000mulbx结果(dx)=000fh,(ax)=4240h

编程:计算data段中第一组数据的3次方,结果存在后面一组dword中

assumecs:code,ds:datadatasegment dw1,2,3,4,5,6,7,8 dd0,0,0,0,0,0,0,0dataendscodesegmentstart: movax,data movds,ax movsi,0 movdi,0 movcx,8 s: movax,ds:[si] callcube movds:[16+di],ax movds:[16+di+2],dx addsi,2 adddi,4 loops movax,4c00h int21h cube: movbx,ax mulbx mulbx ret codeendsendstart批量数据的传递把批量数据放到内存中,然后把他们所在内存空间的首地址放到寄存器。

assumecs:codedatasegment db'Welcometomasm!',0dataendscodesegmentstart: movdh,8 movdl,3 movcl,2 movax,data movds,ax movsi,0 callshow_str movax,4c00h int21hshow_str: moval,160 muldh movdi,ax adddl,dl movdh,0 adddi,dx movax,0B800h moves,ax movdl,cl;dl存颜色信息 movch,0 s: movcl,[si] jcxzok moves:[di],cl moves:[di+1],dl incsi adddi,2 jmpshorts ok:ret codeendsendstart实验10-2

assumecs:code,ds:datadatasegment dw0,0,0,0,0;分别存被除数的低16位,高16位,除数;公式右半部分商,余数dataendscodesegmentstart: movax,data movds,ax movax,4240h movdx,000fh movcx,0ah movds:[0],ax movds:[2],dx movds:[4],cx calldivdw movcx,4c00h int21h divdw: movax,ds:[2] movdx,0 divcx;rem(H/N)结果在dx movax,ds:[0] divcx;公式右半部分结果,商在ax,余数在dx movds:[6],ax movds:[8],dx movax,ds:[2] movdx,0 divcx;int(H/N)结果在ax movdx,ax movax,ds:[6] movcx,ds:[8] retcodeendsendstart 改进:

assumecs:codestacksegment dw0,0,0,0,0stackendscodesegmentstart: movax,stack movss,ax movsp,10 movax,4240h movdx,000fh movcx,0ah calldivdw movcx,4c00h int21h divdw: pushax movax,dx movdx,0 divcx;int(H/N)--ax,rem(H/N)--dx movbx,ax;bx:int(H/N) popax divcx;[res(H/N)*65536+L]/N movcx,dx movdx,bx retcodeendsendstart 实验10-3

assumecs:codedisplaycontentsegment db10dup(0)displaycontentendstmpsegment;用于逆序 db10dup(0)tmpendscodesegmentstart: movax,12666 movbx,tmp moves,bx movbp,0 movbx,displaycontent movds,bx movsi,0 calldtoc;转换到10进制的字符并存到displaycontent中 movdh,8;开始准备显示displaycontent中的内容 movdl,3 movcl,2 movsi,0 callshow_str movax,4c00h int21h dtoc: movdx,0 movcx,10 divcx;ax:商,dx:余数 adddx,30h moves:[bp],dl movcx,ax jcxzdtocok incbp jmpshortdtocdtocok: moval,es:[bp] movds:[si],al movcx,bp jcxzok_1 incsi decbp jmpshortdtocok ok_1:ret show_str: moval,160 muldh movdi,ax adddl,dl movdh,0 adddi,dx movax,0B800h moves,ax movdl,cl;dl存颜色信息 movch,0 s: movcl,[si] jcxzok moves:[di],cl moves:[di+1],dl incsi adddi,2 jmpshorts ok:retcodeendsendstart课程设计1

0--CF进位标志位无符号数运算产生进位CF=1

OF有符号数运算超过机器所能表示的范围产生溢出。例如8位al寄存器范围,如果是有符号数,-128~127溢出针对有符号数,进位针对无符号数!

adc指令adc操作对象1操作对象2功能:操作对象1+操作对象2+CF

moval,98haddal,98hadcah,0执行后(ah)=1

movax,2movbx,1subbx,ax;借位,CF=1adcax,1执行后(ax)=4编程计算1EF000H+201000H,结果放在ax(高16位)和bx(低16位)中:

assumecs:codecodesegmentstart: movbx,0f000h movax,1eh addbx,1000h adcax,20h movax,4c00h int21hcodeendsendstartadc指令也可能改变CF!编程计算1EF0001000h+2010001EF0H结果放在ax+bx+cx中

assumecs:codecodesegmentstart: movcx,1000h movbx,0f000h movax,1eh addcx,1ef0h adcbx,1000h adcax,20h movax,4c00h int21hcodeendsendstart计算两个128位数据的和:

assumecs:code,ds:datadatasegment db88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h db88h,88h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11hdataendscodesegmentstart: movax,data movds,ax movsi,0 movdi,16 movcx,8 subax,ax calladd128 movax,4c00h int21h add128: movax,[si] adcax,[di] mov[si],ax incsi;必须inc,不可以add,inc不影响CF incsi incdi incdi loopadd128 retcodeendsendstartsbb借位减法指令sbbax,bx(ax)=(ax)-(bx)-CF计算003E1000H-00202000H

assumecs:code,ds:datadatasegment db8,11,8,1,8,5,8,38dataendscodesegmentstart: movax,data movds,ax movsi,0 movax,0 movcx,8 s: movbl,[si] cmpbl,8 jneskip incax skip: incsi loops movax,4c00h int21hcodeendsendstart小于8:

assumecs:code,ds:datadatasegment db8,11,8,1,8,5,8,38dataendscodesegmentstart: movax,data movds,ax movsi,0 movax,0 movcx,8 s: movbl,[si] cmpbl,8 jnbskip incax skip: incsi loops movax,4c00h int21hcodeendsendstartDF标志和串传送指令DF:方向标志位在串处理指令中,控制每次操作后si,di的增减

把前面的字符串复制到后面:

assumecs:code,ds:datadatasegment db'Welcometomasm!' db16dup(0)dataendscodesegmentstart: movax,data movds,ax moves,ax movsi,0 movdi,16 movcx,16 cld repmovsb movax,4c00h int21hcodeendsendstart把F000H段中最后16个字节数据存到data段中:

assumecs:code,ds:datadatasegment db16dup(0)dataendscodesegmentstart: movax,0F000h movds,ax movax,data moves,ax movsi,0ffffh movdi,15 movcx,16 std repmovsb movax,4c00h int21hcodeendsendstartpushf和popfpushf:将标志寄存器的值入栈popf:从栈中弹出数据,送入标志寄存器

实验11:将data中数据的小写字母转为大写

assumecs:codesgdatasgsegmentdb"Beginner'sAll-purposeSymbolicInstructionCode.",0datasgendscodesgsegmentstart:movax,datasgmovds,axmovsi,0calllettercmovax,4c00Hint21Hletterc:movcl,[si] movch,0d076a:0d jcxzdone cmpcl,97 jbskip cmpcl,122 jaskip andcl,11011111B mov[si],cl skip: incsi jmpshortletterc done: retcodesgendsendstart内中断在中断过程中,寄存器的入栈顺序是标志寄存器,CS,IP,而iret的出栈顺序为IP,CS,标志寄存器,刚好对应。中断处理程序的cs和ip存放在0000:0000--0000:03FF中,即中断向量表。一般,0000:0200--0000:02FF的256字节是空的,是一段安全的内存空间。ip在低地址,cs在高地址N号中断的处理程序的ip在4N,cs在4N+2一个中断处理程序占4个字节,前两个字节是ip,后两个是cs

编程处理0号中断:

assumecs:codecodesegmentstart: movax,cs movds,ax movsi,offsetdo0 movax,0 moves,ax movdi,0200h movcx,offsetdo0end-offsetdo0;计算do0程序段的长度 cld repmovsb movax,0 movds,ax movdx,0200h movds:[0],dx;0号中断处理程序的ip movdx,0 movds:[2],dx ;cs movax,4c00h int21h do0:jmpshortdo0start;此程序将要放到内存0:0200处 db"Notgood,0#INT!",0do0start:movax,0 movds,ax movax,0B800h moves,ax movsi,0202h movdi,7*160+20 movch,0s: movcl,[si] jcxzdone moves:[di],cl movcl,02h moves:[di+1],clincsi adddi,2jmpshorts done:movax,4c00h int21hdo0end:nop codeendsendstart单步中断CPU在执行完一条指令后,如果监测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码是1引发的中断过程如下:

cpu执行intn指令,相当于引发一个n号中断的中断过程,过程如下:

例1编写int7ch的中断处理函数并安装在中断例程的最后,使用iret指令iret指令的功能为:popippopcspopf中断程序及安装:

assumecs:codecodesegmentstart:movax,cs movds,ax movsi,offsetsqr movax,0 moves,ax movdi,200h movcx,offsetsqrend-offsetsqr cld repmovsb movax,0 movds,ax movax,200h movds:[7ch*4],ax;修改7ch中断的中断处理函数的ip movax,0 movds:[7ch*4+2],ax movax,4c00h int21hsqr:mulax iret sqrend:nopcodeendsendstart测试程序:

assumecs:codecodesegmentstart:movax,3456 int7ch addax,ax adcdx,dx movax,4c00h int21hcodeendsendstart例2转换字符串为大写中断例程及安装:

assumecs:codecodesegmentstart:movax,cs movds,ax movsi,offsetsqr movax,0 moves,ax movdi,200h movcx,offsetsqrend-offsetsqr cld repmovsb movax,0 movds,ax movax,200h movds:[7ch*4],ax;修改7ch中断的中断处理函数的ip movax,0 movds:[7ch*4+2],ax movax,4c00h int21hsqr:movcl,ds:[si] movch,0jcxzdoneandcl,11011111b movds:[si],cl incsi jmpshortsqr done:iret sqrend:nopcodeendsendstart用到中断的程序:

assumecs:codedatasegment db'conversation',0dataendscodesegmentstart:movax,data movds,ax movsi,0 int7ch movax,4c00h int21hcodeendsendstart例3用int7ch实现loop的功能中断程序:

assumecs:codecodesegmentstart:movax,cs movds,ax movsi,offsetlp movax,0 moves,ax movdi,200h movcx,offsetlpend-offsetlp cld repmovsb movax,0 movds,ax movax,200h movds:[7ch*4],ax;修改7ch中断的中断处理函数的ip movax,0 movds:[7ch*4+2],ax movax,4c00h int21hlp:pushbp movbp,sp deccx jcxzdone addss:[bp+2],bxdone:popbpiretlpend:nopcodeendsendstart测试程序:

assumecs:codecodesegmentstart:movax,0b800h moves,ax movdi,160*10 movbx,offsets-offsetse movcx,80s:movbyteptres:[di],'!' adddi,2 int7ch;int时,压栈的ip是se的位置,此ip+bx可以得到s的位置se:nop movax,4c00h int21hcodeendsendstartint10h

movah,2;2号子程序:放置光标movbh,0;第0页movdh,5;dh中放行号movdl,12;dl中放列号int10h(ah)=2表示调用第10h号中断例程的2号子程序,功能为设置光标位置

movah,9moval,'a';字符movbl,7;颜色属性movbh,0;第0页movcx,3;重复个数int10h9号子程序,功能为在光标位置显示字符。int21h

ds:dx指向字符串;要显示的字符串需要用$作为结束符movah,9int21h在光标位置显示字符串,可以提供要显示的字符串的地址作为参数。实验13_1中断程序及安装:

assumecs:codecodesegmentstart: movax,cs movds,ax movsi,offsetintcode movax,0 moves,ax movdi,0200h movcx,offsetintcodeend-offsetintcode cld repmovsb movax,0 movds,ax movwordptrds:[7ch*4],0200h movwordptrds:[7ch*4+2],0 movax,4c00h int21hintcode:moval,160 muldh movdi,ax adddl,dl movdh,0 adddi,dx movax,0B800h moves,ax movdl,cl movch,0 s: movcl,ds:[si] jcxzdone moves:[di],cl moves:[di+1],dl incsi adddi,2 jmpshortsdone:iretintcodeend:nopcodeendsendstart测试中断的程序:

assumecs:codedatasegment db"welcometomasm!",0dataendscodesegmentstart: movdh,10 movdl,10 movcl,2 movax,data movds,ax movsi,0 int7ch movax,4c00h int21hcodeendsendstart实验13_2中断程序及安装:

assumecs:codecodesegmentstart: movax,cs movds,ax movsi,offsetintcode movax,0 moves,ax movdi,0200h movcx,offsetintcodeend-offsetintcode cld repmovsb movax,0 movds,ax movwordptrds:[7ch*4],0200h movwordptrds:[7ch*4+2],0 movax,4c00h int21hintcode:deccx jcxzdone movbp,sp addss:[bp],bxdone: iretintcodeend:nopcodeendsendstart测试程序:

assumecs:codecodesegmentstart:movax,0b800h moves,ax movdi,160*12 movbx,offsets-offsetse movcx,80 s: movbyteptres:[di],'!' adddi,2 int7chse:nop movax,4c00h int21hcodeendsendstart实验13_3

assumecs:codecodesegments1: db'Good,better,best,','$'s2: db'Neverletitrest,','$'s3: db'Tillgoodisbetter,','$'s4: db'Andbetter,best.','$'s: dwoffsets1,offsets2,offsets3,offsets4row: db2,4,6,8start:movax,cs movds,ax movbx,offsets movsi,offsetrow movcx,4 ok:movbh,0;第0页 movdh,[si];dh中放行号 movdl,0;dl中放列号 movah,2;2号子程序:放置光标 int10h movdx,[bx];ds:dx指向字符串要显示的字符串需要用$作为结束符 movah,9;在光标位置显示字符串 int21h incsi addbx,2 loopok movax,4c00h int21hcodeendsendstart端口端口的读写读写指令只有两条:in和outinal,60h从60h号端口读入一个字节out21h,al向21h端口写al注意,只能用al或者ax

movdx,3f8hinal,dxoutdx,alCMOSRAM芯片包含128个存储单元该芯片靠电池供电,断电后仍可继续工作,信息不丢失。时钟占用0-0dh单元,其余大部分单元保存系统配置信息,供系统启动时BIOS程序读取。该芯片有两个端口,70h和71h,cpu通过这两个端口读写CMOSRAM70h为地址端口,存放要访问的CMOSRAM单元的地址;71h为数据端口,存放从选定的CMOSRAM单元中读取的数据,或者要写入的数据。读2号单元:

assumecs:codecodesegmentstart:moval,2 out70h,al inal,71h movax,4c00h int21hcodeendsendstart向2号存储单元写入0:

assumecs:codecodesegmentstart:moval,2 out70h,al moval,0 out71h,al movax,4c00h int21hcodeendsendstartshr,shlshl逻辑左移,将一个寄存器或者内存单元中的数据向左移位,最后移出的一位写入CF。

moval,01001000bshlal,1执行后(al)=10010000B,CF=0如果移位位数大于1,必须将位数放在cl中。比如:

moval,01010001Bmovcl,3shlal,cl执行后(al)=10001000b,CF=0

计算(ax)=(ax)*10

编写int9例程,每次按下esc,改变显示字符颜色:

assumecs:codestacksegment db128dup(0)stackendscodesegmentstart:movax,0 moves,ax;es:0 movdi,0204h movax,cs movds,ax;ds:cs movsi,offsetint9 movcx,offsetint9end-offsetint9 cld repmovsb movax,stack movss,ax movsp,128 pushes:[9*4] popes:[200h] pushes:[9*4+2] popes:[202h] movax,204h moves:[9*4],ax movax,0 moves:[9*4+2],ax movax,4c00h int21h int9: pushax pushds pushcx pushbx inal,60h pushf calldwordptrcs:[200h] cmpal,3bh jneint9ret movax,0b800h moves,ax movbx,1 movcx,2000 s:incbyteptres:[bx] addbx,2 loops int9ret:popbx popcx popds popax iret int9end:nopcodeendsendstart实验15安装新的int9中断例程

assumecs:codestacksegment db128dup(0)stackendscodesegmentstart:movax,0 moves,ax;es:0 movdi,0204h movax,cs movds,ax;ds:cs movsi,offsetint9 movcx,offsetint9end-offsetint9 cld repmovsb movax,stack movss,ax movsp,128 pushes:[9*4] popes:[200h] pushes:[9*4+2] popes:[202h] movax,204h moves:[9*4],ax movax,0 moves:[9*4+2],ax movax,4c00h int21h int9: pushax pushes pushcx pushbx inal,60h pushf calldwordptrcs:[200h] cmpal,9eh jneint9ret movax,0b800h moves,ax movbx,0 movcx,2000 s:movbyteptres:[bx],'A' addbx,2 loops int9ret:popbx popcx popes popax iret int9end:nopcodeendsendstart直接定址表adb1,2,3,4,5,6,7,8bdw0start:moval,a[si];相当于moval,cs:0[si]moval,a[3];相当于moval,cs:0[3]movax,b;movax,cs:[8]movb,2;movwordptrcs:[8],2incb;incwordptrcs:[8]将a处的8个数据相加结果存到b处的双字中:

assumecs:codecodesegment adw1,2,3,4,5,6,7,8 bdd0 start:movsi,0 movcx,8 s:movax,a[si] adda[16],axadca[18],0 addsi,2loops movax,4c00h int21hcodeendsendstart 若将数据放在数据段,则必须assume

assumecs:code,ds:datadatasegment adb1,2,3,4,5,6,7,8 bdw0dataendscodesegmentstart:movax,data movds,ax movsi,0 movcx,8 s:moval,a[si] movah,0 addb,ax incsiloops movax,4c00h int21hcodeendsendstart 如果想在代码段中直接用数据标号访问数据,则需要用伪指令assume将标号所在的段和一个段寄存器联系起来。否则编译器在编译时无法确定标号的段地址在哪儿一个寄存器中。

datasegmentadb1,2,3,4,5,6,7,8bdw0cdda,bdataendsc处存储的两个双子为标号a的偏移地址和段地址,标号b的偏移地址和短地址。相当于

datasegmentadb1,2,3,4,5,6,7,8bdw0cdwoffseta,sega,offsetb,segbdataends应用:以16进制形式显示数字

assumecs:code,ds:datadatasegment tabledb'0123456789ABCDEF'dataendscodesegmentstart:movax,data movds,ax movax,0b800h moves,ax movdi,160*10+40 moval,0eh movah,al shrah,1 shrah,1shrah,1shrah,1 movbl,ah movbh,0 movah,table[bx] moves:[di],ah movah,02h moves:[di+1],ah andal,00001111b movbl,al movbh,0 movah,table[bx] moves:[di+2],ah movah,02h moves:[di+3],ahmovax,4c00h int21hcodeendsendstart 另一个应用,计算sin

movah,0int16h结果:(ah)=扫描码,(al)=ASCII码int16h中断例程的0号功能进行如下工作:

assumecs:codecodesegmentstart: movah,0 int16h cmpal,'r' jered cmpal,'g' jegreen cmpal,'b' jeblue red:movah,00000100b jmpshorts green:movah,00000010b jmpshorts blue:movah,00000001b s:movbx,0b800h moves,bx movbx,1 movcx,2000 s1:andbyteptres:[bx],11111000b ores:[bx],ah addbx,2 loops1 movax,4c00h int21hcodeendsendstart

THE END
1....潘甜甜16岁拍的电视原著是什么sp用数据线打有多疼数字经济既是构成新质生产力的主要内容,也是驱动新质生产力发展的关键因素。爱尔眼科更是紧跟时代步伐,加速推进“数字眼科”发展新模式,助力眼病防治效率和精准性不断提升*。 自2018年起,爱尔眼科就启动了数字化转型。依托遍布全球的专业眼科医院和中心累积的海量数据,爱尔眼科建立了眼健康大数据中心,并...http://14068.xuanweisdk.com/
2.由8086CPU组成PC机的数据线是()由8086CPU组成PC机的数据线是() A.8根单向线 B.16根单向线 C.8根双向线 D.16根双向线 点击查看答案进入题库练习 查答案就用赞题库小程序 还有拍照搜题 语音搜题 快来试试吧 无需下载 立即使用 你可能喜欢 单项选择题 8086CPU中寄存器()通常用作数据寄存器,且隐含用法作为I/O指令间接寻址时的端口地址...https://m.ppkao.com/mip/tiku/shiti/7789667.html
3.《单片计算机及其应用》讲义线和数据总线采用分时复用等。 1、存储结构。 采用 ROM和 RAM严格分 开的哈佛结构,可分为:内部 ROM、 RAM,外部 ROM,RAM。 3、特殊功能寄存器 (21个 ) 采用特殊功能寄存器 来控制单片机的功能状态,如定时 /计数器、 串行口和中断逻辑等。 4、全双工串行接口 内部具有全双工串行接口, ...http://read.cucdc.com/cw/62480/144694.html
4.智能手机(SP版)修改手册SP支持两种方式和笔记本连接,分别是红外线和usb数据线连接,并且可以使笔记本通过SPgprs 无线上网,让你随时随地都可以无线互联,将无线应用发挥到极致。下面简单说明一下笔记本红外 连接SP并通过gprs上网的简单设置,usb连接与此类似。 1、确认gprs开通和SP的gprs设置: ...https://www.360doc.cn/article/73_60068.html
1.Look!!!苹果数据线还可以这样玩!!!没有的知识又增长了Look!!!苹果数据线还可以这样玩!!!没有的知识又增长了 今天看看线线,看看手腕,没想到,一试,哇好哒,没电了直接取下来,直接就是全场最亮的仔,哈哈哈哈哈,我真的很佩服自己,这款的线,充电是快充呢#充电线磁吸数据线 #快充插线板 #快充数据线 #充电线数据线 #安卓充电线 @得物App @得物好物分享 @得物创...https://m.dewu.com/note/trend/details?id=248661673
2.微机原理第2章微处理器微机原理地址②CPU执行指令时,总线接口单元要配合EU,从指定的主存单元或外设端口中取数据将数据传送给EU,或把EU的操作结果传送到指定的主存单元或外设端口中。 ③计算并形成访问存储器的20位物理地址<8086有20根地址线>。 (2)BIU的组成 BIU由4个16位段寄存器(CS、DS、SS、ES)、16位指令指针寄存器(IP)、20位物理地址加法...https://blog.csdn.net/qq_59467552/article/details/128298800
3.嵌入式笔试面试题目系列(汇总)腾讯云开发者社区SCL=1时 数据线SDA的任何电平变换会看做是总线的起始信号或者停止信号。 IIC我也有一篇文章有讲解,请看链接: IIC总线最多可以挂多少个设备 5、单片机的SP指针始终指向 栈顶 6、IIC总线在传送数据过程中共有三种类型信号: 它们分别是:开始信号、结束信号和应答信号。 7、FIQ中断向量入口地址: FIQ和IRQ是两种不同...https://cloud.tencent.com/developer/article/1829282
4.MCU内部架构及程序运行原理讲解技术分享MISO:数据引脚,Slave发送给Master的数据线; Master读写操作同时进行,Master发送片选信号和时钟信号,然后每个时钟周期MOSI和MISO同步传输数据。 c、SPI串行外设接口 用于连接外部较高速度的模块,通信速度明显高于连接部分模块例如陀螺仪、高度计等传感器,支持SPI接口通信。SPI接口连接外部SPI Flash一种常见的用法,这种 Flash...https://www.zovps.com/article/index.php/post/125042.html
5.微机原理与接口技术顾晖习题参考答案(精选8篇)5.3 8086CPU和8088CPU是怎样解决地址线和数据线的复用问题的?ALE#信号何时处于有效电平 【解】8086/8088CPU利用分时时序信号解决地址线和数据线的复用问题。在总线周期的T1状态在复用线上输出地址信号及地址锁存信号ALE#,供外部电路锁存地址信息;从T2状态开始将复用线切换为数据状态,用于传送数据。 6.4 若要扩充1KB ...https://www.360wenmi.com/f/fileb2rf3sc3.html
6.微机的接口技术披风逐月的技术博客但是实际上,实模式的地址长度有20位,保护模式的地址长度有32位。那么还有2位地址线A0和A1到哪里去了呢?原来这两位地址被微处理器内部译码,与数据传输的字节数(数据宽度)一起产生字节允许信号用以支持按4个独立的字节宽度的存储体(Bank0~Bank3)来组织32位存储器地址空间和I/O地址空间了。http://jkers.blog.51cto.com/3016670/1086537
7.「正点原子STM32Mini板资料连载」第十六章TFTLCD显示实验模块的 80 并口有如下一些信号线: CS:TFTLCD 片选信号。 WR:向 TFTLCD 写入数据。 RD:从 TFTLCD 读取数据。 D[15:0]:16 位双向数据线。 RST:硬复位 TFTLCD。 RS:命令/数据标志(0,读写命令;1,读写数据)。 80 并口在上一节我们已经有详细的介绍了,这里我们就不再介绍,需要说明的是,TFTLCD ...https://bbs.elecfans.com/m/jishu_1919810_1_1.html
8.sp用数据线打有多疼1988 大陆 惊悚 《sp用数据线打有多疼》剧情简介:#文末有福利果然……侵吞了太古青天碎片就算有天灵也变得愚昧懵懂了方源眼底闪过一丝精芒心中了然sp用数据线打有多疼就在这个时候第三蛊对他说:人啊你供奉我吧我能让你脱离困境在这里也希望广大的网友朋友在关注和讨论这件事情的时候一定要保持冷静和理性不要随意...http://down.bypos.net/curs/u8gza1z.aspx
9.OrangePi5PlusWikiType-C接口的数据线,用于烧录镜像、使用ADB等功能 红外遥控器 注意,空调遥控或者电视机的遥控是无法控制Orange Pi开发板的,Orange Pi提供的操作系统默认只能保证Orange Pi提供的遥控器才可以使用。 1300万MIPI接口的OV13850摄像头(和OPi5/OPi5B通用) 1300万MIPI接口的OV13855摄像头(和OPi5/OPi5B通用) ...http://www.orangepi.cn/orangepiwiki/index.php?title=Orange_Pi_5_Plus&oldid=3914&printable=yes
10.{管理信息化VR虚拟现实}ELTABARMII2410说明书液晶线时钟 O 70 VCLK 液晶位时钟 O 71 VD0 液晶数据 0 O 72 VD1 液晶数据 1 O 73 VD2 液晶数据 2 O 74 VD3 液晶数据 3 O 75 VD4 液晶数据 4 O 76 VD5 液晶数据 5 O 77 VD6 液晶数据 6 O 78 VD7 液晶数据 7 O 79 GND 地 80 GND 地 表 1-9 实验箱底板的资源介绍 1.概述 实验...https://doc.mbalib.com/view/6f8154620389af4c8e3fc02a245f59e6.html