基于8086用汇编语言实现的十个有符号数的排序(冒泡排序算法,输入为补码,从小到大)
汇编语言输入10个数排序并输出的实现

汇编语⾔输⼊10个数排序并输出的实现⼀:题⽬描述在键盘输⼊任意10个数1. 按从⼩到⼤排序后,在计算机屏幕上先输出来。
要有结果提⽰(字符串显⽰)。
2. 将10个数做累加,结果在计算机屏幕显⽰累加和。
⼆:伪指令的定义1.数据段ATAS SEGMENTstring_1 DB 'Please input a numbers(0-65536):','$'string_2 DB 'ERROR: OVERFLOW! Please input again:','$'string_3 DB 'The array you have input is:',0ah,0dh,'$'string_4 DB 'After Sort the num is:',0ah,0dh,'$'string_5 DB ' ','$'DATA DW 10 DUP(?)massege DB 'The sum of the array is: ',0ah,0DH,'$'DATAS ENDS说明:string_1输⼊范围提⽰string_2输⼊错误提⽰string_3输出原数组提⽰string_4输出排序后数组提⽰string_5空格符DATA缓冲区数组2.堆栈段STACKS SEGMENTDW 256 dup(?)STACKS ENDS3.代码段CODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS三:模块分解与实现1. DOS输⼊10个数字输⼊10个⽆符号数存⼊缓冲区,并且保证 num<65536num < 65536num<65536为何输⼊范围是65536呢⼀个字的最⼤表⽰范围是 FFFFFFFFFFFF 其在⼗进制的表⽰下为 65535HEX FFFFDEC65535BIN1111 1111 1111 11111.1 输⼊函数⼦程序;---------输⼊函数(单数字输⼊)------------Input PROC Nearpush AXpush BXpush CXpush DX;---------输⼊提⽰--------------MOV BX, 0CLCMOV DX, 0;----------输⼊数字--------------Lp_0:MOV AH, 1INT 21HCMP AL, 20H ;回车JE L_CRLF;----- x belong to [0,9] ----------SUB AL, 30H ; ASCII -> intJL L_ERRORCMP AL, 9JG L_ERROR;------- string -> int -----------MOV AH, 0 ;将 AL扩展成 AXXCHG AX, BX ;保护 AX值MOV CX, 10MUL CX ; bx *= 10ADD AX , BXJC L_ERROR ; OVERFLOW处理XCHG AX, BXJMP Lp_0L_ERROR:MOV DX, 0MOV BX, 0CALL CRLF ; 换⾏CALL ERROR ; 输出错误提⽰JMP Lp_0L_CRLF: ; 以换⾏作为⼀个数的结束标志MOV DX, 0MOV DATA[SI], BX ;解析函数功能:本质类似于⾼精度计算,将读⼊的⼀个串转成数字存储在DATA数组中分成三⼤部分⼀:输⼊提⽰⼆:错误判断及提⽰三:转化为数字L_ERROR 错误处理L_CRLF 结束处理我们来举⼀个123412341234 的例⼦Register1234AX1234BX0112123CX10101010AX+(BX∗CX)AX + (BX * CX)AX+(BX∗CX)最后将结果存储在DATA数组⾥2.实现冒泡排序冒泡排序作为⼀个简单的排序算法,时间复杂度 O(n2)O(n^2)O(n2) 需要两层循环,为了提⾼代码的可读性,我们将内层的循环写成⼀个⼦程序每次调⽤内层循环很简单,每次从头⽐到尾,遇到⽐它⼩的交换就可以了。
(完整版),汇编语言速成秘籍,推荐文档

(算术运算
商,AH←AX÷src 余 8 位 mem (86~96)+EA
指令)
数,Src 字 AX←DX 16 位 reg 144 ~ 162
AX÷src 商,DX←DX 16 位 mem (150~168)+EA
AX÷src 余数
IDIV src Src 字节AL←AX÷src 8 位 reg 101 ~ 112
经计算才能得到操作 (AL)←((DS)×16+(SI)+OFFSET)
数
MOV AX,[BX+DI];
(AX)←((DS)×16+(BX)+(DI))
1
8086 汇编总结 相对基址变址寻址
PA=(DS|SS)×16+ (BX|BP)+(SI|DI)+偏移量
程伟整理 MOV AX, OFFSET (BX+DI); (AX)←((DS)×16+(BX)+(DI)+OFFS ET)
标志 F 标志寄存器
,
标志寄存器
总线 段 接口 寄 部件 存 BIU 器
CS 代码段 DS 数据段 ES 附加段 SS 堆栈段
不能被赋值 复位后为 FFFFH 复位后为 0000H
存放堆栈基地址
存储器
IP IP 指令指针寄存器器
指令指针寄存器
二、状态标志寄存器 F
标志位名
功能
为 1 对应符
为 0 对应符
16+EA 9+EA
指令)
reg, reg
3
reg, imm 4
mem, imm 17+EA
SBBdest ,src
(dst) ← (src) - (dst) - mem, reg
8086的汇编超级浓缩教程

“哎哟,哥们儿,还捣鼓汇编呢?那东西没用,兄弟用VB"钓"一个API就够你忙活个十天半月的,还不一定搞出来。
”此君之言倒也不虚,那吾等还有无必要研他一究呢?(废话,当然有啦!要不然你写这篇文章干嘛。
)别急,别急,让我把这个中原委慢慢道来:一、所有电脑语言写出的程序运行时在内存中都以机器码方式存储,机器码可以被比较准确的翻译成汇编语言,这是因为汇编语言兼容性最好,故几乎所有跟踪、调试工具(包括WIN95/98下)都是以汇编示人的,如果阁下对CRACK颇感兴趣……;二、汇编直接与硬件打交道,如果你想搞通程序在执行时在电脑中的来龙去脉,也就是搞清电脑每个组成部分究竟在干什么、究竟怎么干?一个真正的硬件发烧友,不懂这些可不行。
三、如今玩DOS的多是“高手”,如能像吾一样混入(我不是高手)“高手”内部,不仅可以从“高手”朋友那儿套些黑客级“机密”,还可以自诩“高手”尽情享受强烈的虚荣感--#$%& “醒醒!”对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。
所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。
某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。
为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ……)。
但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP、WINRAR…依次压迫,嘿嘿!)教程。
大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么――这个接下来呢?――Here we go!(阅读时看不懂不要紧,下文必有分解)因为汇编是通过CPU和内存跟硬件对话的,所以我们不得不先了解一下CPU和内存:(关于数的进制问题在此不提)CPU是可以执行电脑所有算术╱逻辑运算与基本I/O 控制功能的一块芯片。
基于8086用汇编语言实现的十个有符号数的排序(冒泡排序算法,输入为补码,从小到大)

提示:在做实验时,我们要自己将代码区和数据区分开,因为8086上没有软件帮我们完成这个任务。
MOV R0,#218 //之所以选择208这个大点的地址,是因为避免将数据写到了代码区LOOP1:IN //将数据读入AADD A,#128 //将补码转换为其对应的移码,因为补码本身参与加减不能比较出大//小,而移码就是将其真值在数轴上平移了2的n次方MOV @R0,AMOV A,R0sub a,#1SUB A,#208 //判断有没有输入完10个数JZ LOOP2 //输入完数据,跳转ADD A,#208MOV R0,AJMP LOOP1//没有输入完,就跳回接着输入LOOP2:MOV R0,#9 //9轮循环比较就可以排完序MOV R1,#209MOV R2,#210LOOP4:MOV A,@R2SUBC A,@R1JC LOOP3 //若210地址指向的单元中的数比209地址指向的单元中的小,则交//换LOOP5:MOV A,R2ADD A,#1SUBC A,#219 //判断此轮有没有比较完JZ LOOP6 //若比较完,就跳到LOOP6,否则继续比较ADD A,#219MOV R2,AJMP LOOP4LOOP3:MOV A,@R1MOV 208,AMOV A,@R2MOV @R1,AMOV A,208MOV @R2,AJMP LOOP5 //交换完了就跳回LOOP6: MOV A,R1ADD A,#1MOV R1,AADD A,#1MOV R2,A //让R2始终指向的是R1下一个单元MOV A,R0SUB A,#1JZ LOOP7 //判断9轮比较有没有完成,若完成,跳LOOP7,否则,继续比//较MOV R0,AJMP LOOP4LOOP7: MOV R0,#218LOOP9: MOV A,@R0 //下面这一段代码就是将数还原,因为原来我们是那人家的移码//形式来比较的,相信下面这一段就不用多讲了吧ADD A,#128MOV @R0,AMOV A,R0sub a,#1SUB A,#208JZ LOOP8ADD A,#208MOV R0,AJMP LOOP9LOOP8:END。
8086-汇编指令集

8086 汇编指令集一、数据传输指令它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.1. 通用数据传送指令MOV 传送字或字节.格式为: MOV DST,SRC执行的操作:(DST)<-(SRC)MOVSX 先符号扩展,再传送.MOVZX 先零扩展,再传送.PUSH 把字压入堆栈.格式为:PUSH SRC执行的操作:(SP)<-(SP)-2 ((SP)+1,(SP))<-(SRC)POP 把字弹出堆栈.格式为:POP DST执行的操作:(DST)<-((SP+1),(SP)) (SP)<-(SP)+2PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI 依次压入堆栈.POPA 把DI,SI,BP,SP,BX,DX,CX,AX 依次弹出堆栈.PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI 依次压入堆栈.POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX 依次弹出堆栈.BSWAP 交换32 位寄存器里字节的顺序XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)格式为:XCHG OPR1,OPR2执行的操作:(OPR1)<-->(OPR2)CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )XADD 先交换再累加.( 结果在第一个操作数里)2. 输入输出端口传送指令.IN I/O 端口输入. ( 语法: IN 累加器,{端口号│DX} )长格式为:IN AL,PORT(字节)IN AX,PORT(字)执行的操作:(AL)<-(PORT)(字节)(AX)<-(PORT+1,PORT)(字)短格式为:IN AL,DX(字节)IN AX,DX(字)执行的操作: AL<-((DX))(字节)AX<-((DX)+1,DX)(字)OUT I/O 端口输出. ( 语法: OUT {端口号│DX},累加器),输入输出端口由立即方式指定时,其范围是0-255;由寄存器DX 指定时,其范围是0-65535.长格式为: OUT PORT,AL(字节)OUT PORT,AX(字)执行的操作: (PORT)<-(AL)(字节)(PORT+1,PORT)<-(AX)(字)短格式为: OUT DX,AL(字节)OUT DX,AX(字)执行的操作: ((DX))<-(AL)(字节)((DX)+1,(DX))<-AX(字)XLAT 换码指令字节查表转换,BX 指向一张256 字节的表的起点,AL 为表的索引值(0-255,即0-FFH);返回AL 为查表结果. 执行的操作: ( [BX+AL]->AL )格式为: XLAT OPR或: XLAT3. 目的地址传送指令.LEA 装入有效地址. 格式为: LEA REG,SRC执行的操作:(REG)<-SRC指令把源操作数的有效地址送到指定的寄存器中.例: LEA DX,string ;把偏移地址存到DX.LDS 传送目标指针,把指针内容装入DS.格式为: LDS REG,SRC执行的操作:(REG)<-(SRC) (DS)<-(SRC+2)把源操作数指定的 4 个相继字节送到由指令指定的寄存器及DS 寄存器中.该指令常指定SI寄存器.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.LES 传送目标指针,把指针内容装入ES.格式为: LES REG,SRC执行的操作: (REG)<-(SRC) (ES)<-(SRC+2)把源操作数指定的 4 个相继字节送到由指令指定的寄存器及ES 寄存器中.该指令常指定DI寄存器.例: LES DI,string ;把段地址:偏移地址存到ES:DI.LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.4. 标志传送指令.LAHF 标志寄存器传送,把标志装入AH.格式为: LAHF执行的操作:(AH)<-(PWS 的低字节)SAHF 标志寄存器传送,把AH 内容装入标志寄存器.格式为: SAHF执行的操作:(PWS 的低字节)<-(AH)PUSHF 标志入栈.格式为: PUSHF执行的操作:(SP)<-(SP)-2 ((SP)+1,(SP))<-(PSW)POPF 标志出栈.格式为: POPF执行的操作:(PWS)<-((SP)+1,(SP)) (SP)<-(SP+2)PUSHD 32 位标志入栈.POPD 32 位标志出栈.二、算术运算指令ADD 加法.格式: ADD DST,SRC执行的操作:(DST)<-(SRC)+(DST)ADC 带进位加法.格式: ADC DST,SRC执行的操作:(DST)<-(SRC)+(DST)+CFINC 加1.格式: INC OPR执行的操作:(OPR)<-(OPR)+1AAA 加法的ASCII 码调整.DAA 加法的十进制调整.SUB 减法.格式: SUB DST,SRC执行的操作:(DST)<-(DST)-(SRC)SBB 带借位减法.格式: SBB DST,SRC执行的操作:(DST)<-(DST)-(SRC)-CFDEC 减1.格式: DEC OPR执行的操作:(OPR)<-(OPR)-1NEC 求反(以0 减之).格式: NEG OPR执行的操作:(OPR)<--(OPR)CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).格式: CMP OPR1,OPR2执行的操作:(OPR1)-(OPR2)该指令与SUB 指令一样执行减法操作,但不保存结果,只是根据结果设置条件标志. AAS 减法的ASCII 码调整.DAS 减法的十进制调整.MUL 无符号乘法.格式: MUL SRC执行的操作:字节操作数:(AX)<-(AL)*(SRC)字操作数:(DX,AX)<-(AX)*(SRC)IMUL 整数乘法.格式: IMUL SRC执行的操作:与MUL 相同,但必须是带符号数,而MUL 是无符号数.以上两条,结果回送AH 和AL(字节运算),或DX 和AX(字运算),AAM 乘法的ASCII 码调整.DIV 无符号除法.非组合BCD 码乘法调整指令格式: DIV SRC执行的操作:字节操作:(AL)<-(AX)/(SRC)的商(AH)<-(AX)/(SRC)的余数字操作: (AX)<-(DX,AX)/(SRC)的商(AX)<-(DX,AX)/(SRC)的余数IDIV 整数除法.格式: DIV SRC执行的操作:与DIV 相同,但操作数必须是带符号数,商和余数也均为带符号数,且余数的符号与被除数的符号相同.以上两条,结果回送:商回送AL,余数回送AH,(字节运算);或商回送AX,余数回送DX,(字运算).AAD 除法的ASCII 码调整.非组合BCD 码除法调整指令CBW 字节转换为字. (把AL 中字节的符号扩展到AH 中去)格式: CBW执行的操作:AL 的内容符号扩展到AH.即如果(AL)的最高有效位为0,则(AH)=00;如(AL)的最高有效位为1,则(AH)=0FFHCWD 字转换为双字. (把AX 中的字的符号扩展到DX 中去)格式: CWD执行的操作:AX 的内容符号扩展到DX.即如(AX)的最高有效位为0,则(DX)=0;否则(DX)=0FFFFH.这两条指令都不影响条件码.CWDE 字转换为双字. (把AX 中的字符号扩展到EAX 中去)CDQ 双字扩展. (把EAX 中的字的符号扩展到EDX 中去)三、逻辑运算指令AND 与运算.格式: AND DST,SRC执行的操作:(DST)<-(DST)^(SRC)OR 或运算.格式: OR DST,SRC执行的操作:(DST)<-(DST)V(SRC)XOR 异或运算.格式: XOR DST,SRC执行的操作:(DST)<-(DST)V(SRC)NOT 取反.格式: NOT OPR执行的操作:(OPR)<-(OPR)TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).格式: TEST OPR1,OPR2执行的操作:(DST)^(SRC)两个操作数相与的结果不保存,只根据其特征置条件码SHL 逻辑左移.格式: SHL OPR,CNT(其余的类似)其中OPR 可以是除立即数以外的任何寻址方式.移位次数由CNT 决定,CNT 可以是 1 或CL.SAL 算术左移.(=SHL)SHR 逻辑右移.SAR 算术右移.(=SHR)ROL 循环左移.ROR 循环右移.RCL 通过进位的循环左移.RCR 通过进位的循环右移.以上八种移位指令,其移位次数可达255 次.移位一次时,可直接用操作码. 如SHL AX,1.移位>1 次时,则由寄存器CL 给出移位次数.如MOV CL,04SHL AX,CL四、串指令DS:SI 源串段寄存器:源串变址.ES:DI 目标串段寄存器:目标串变址.CX 重复次数计数器.AL/AX 扫描值.D 标志0 表示重复操作中SI 和DI 应自动增量;1 表示应自动减量.Z 标志用来控制扫描或比较操作的结束.MOVS 串传送.格式:可有三种MOVS DST,SRCMOVSB(字节)MOVSW(字)其中第二、三种格式明确地注明是传送字节或字,第一种格式则应在操作数中表明是字还是字节操作,例如:MOVS ES:BYTE PTR[DI],DS:[SI]执行的操作:1)((DI))<-((SI))2)字节操作:(SI)<-(SI)+(或-)1,(DI)<-(DI)+(或-)1当方向标志DF=0 时用+,当方向标志DF=1 时用-3)字操作:(SI)<-(SI)+(或-)2,(DI)<-(DI)+(或-)2当方向标志DF=0 时用+,当方向标志DF=1 时用-该指令不影响条件码.CMPS 串比较.格式: CMPS SRC,DSTCMPSBCMPSW执行的操作:1)((SI))-((DI))2)字节操作:(SI)<-(SI)+-1,(DI)<-(DI)+-1字操作: (SI)<-(SI)+-2,(DI)<-(DI)+-2指令把由(SI)指向的数据段中的一个字(或字节)与由(DI)指向的附加段中的一个字(或字节)相减,但不保存结果,只根据结果设置条件码,指令的其它特性和MOVS 指令的规定相同.SCAS 串扫描.把AL 或AX 的内容与目标串作比较,比较结果反映在标志位.格式: SCAS DSTSCASBSCASW执行的操作:字节操作: (AL)-((DI)),(DI)<-(DI)+-1字操作: (AL)-((DI)),(DI)<-(DI)+-2该指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存结果,只根据结果置条件码.指令的其他特性和MOVS 的规定相同.LODS 装入串.把源串中的元素(字或字节)逐一装入AL 或AX 中.格式: LODS SRCLODSBLODSW执行的操作:字节操作:(AL)<-((SI)),(SI)<-(SI)+-1字操作: (AX)<-((SI)),(SI)<-(SI)+-2该指令把由(SI)指定的数据段中某单元的内容送到AL 或AX 中,并根据方向标志及数据类型修改SI 的内容.指令允许使用段跨越前缀来指定非数据段的存储区.该指令也不影响条件码.一般说来,该指令不和REP 联用.有时缓冲区中的一串字符需要逐次取出来测试时,可使用本指令.STOS 保存串.是LODS 的逆过程.格式: STOS DSTSTOSB(字节)STOSW(字)执行的操作:字节操作:((DI))<-(AL),(DI)<-(DI)+-1字操作: ((DI))<-(AX),(DI)<-(DI)+-2该指令把AL 或AX 的内容存入由(DI)指定的附加段的某单元中,并根据DF 的值及数据类型修改DI 的内容,当它与REP 联用时,可把AL 或AX 的内容存入一个长度为(CX)的缓冲区中.REP 当CX/ECX<>0 时重复.格式: REP string primitive其中String Primitive 可为MOVS,LODS 或STOS 指令执行的操作:1)如(CX)=0 则退出REP,否则往下执行.2)(CX)<-(CX)-13)执行其中的串操作4)重复1)~3)REPE/REPZ 当ZF=1 或比较结果相等,且CX/ECX<>0 时重复.格式: REPE(或REPZ) String Primitive其中String Primitive 可为CMPS 或SCAS 指令.执行的操作:1)如(CX)=0 或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行2)(CX)<-(CX)-13)执行其后的串指令4)重复1)~3)REPNE/REPNZ 当ZF=0 或比较结果不相等,且CX/ECX<>0 时重复.格式: REPNE(或REPNZ) String Primitive其中String Primitive 可为CMPS 或SCAS 指令执行的操作:除退出条件(CX=0)或ZF=1 外,其他操作与REPE 完全相同.REPC 当CF=1 且CX/ECX<>0 时重复.REPNC 当CF=0 且CX/ECX<>0 时重复.五、程序转移指令1>无条件转移指令(长转移)JMP 无条件转移指令1)段内直接短转移格式:JMP SHORT OPR执行的操作:(IP)<-(IP)+8 位位移量2)段内直接近转移格式:JMP NEAR PTR OPR执行的操作:(IP)<-(IP)+16 位位移量3)段内间接转移格式:JMP WORD PTR OPR执行的操作:(IP)<-(EA)4)段间直接(远)转移格式:JMP FAR PTR OPR执行的操作:(IP)<-OPR 的段内偏移地址(CS)<-OPR 所在段的段地址5)段间间接转移格式:JMP DWORD PTR OPR执行的操作:(IP)<-(EA) (CS)<-(EA+2)2>条件转移指令(短转移,-128 到+127 的距离内)1)根据单个条件标志的设置情况转移JZ(或JE)(Jump if zero,or equal) 结果为零(或相等)则转移格式:JE(或JZ) OPR测试条件:ZF=1JNZ(或JNE)(Jump if not zero,or not equal) 结果不为零(或不相等)则转移格式:JNZ(或JNE) OPR测试条件:ZF=0JS(Jump if sign) 结果为负则转移格式: JS OPR测试条件:SF=1JNS(Jump if not sign) 结果为正则转移格式:JNS OPR测试条件:SF=0JO(Jump if overflow) 溢出则转移格式: JO OPR测试条件:OF=1JNO(Jump if not overflow) 不溢出则转移格式: JNO OPR测试条件:OF=0JP(或JPE)(Jump if parity,or parity even) 奇偶位为1 则转移格式: JP OPR测试条件:PF=1JNP(或JPO)(Jump if not parity,or parity odd) 奇偶位为0 则转移格式: JNP(或JPO) OPR测试条件:PF=0JB(或JNAE,JC)(Jump if below,or not above or equal,or carry) 低于,或者不高于或等于,或进位位为1 则转移格式:JB(或JNAE,JC) OPR测试条件:CF=1JNB(或JAE,JNC)(Jump if not below,or above or equal,or not carry) 不低于,或者高于或者等于,或进位位为0 则转移格式:JNB(或JAE,JNC) OPR测试条件:CF=02)比较两个无符号数,并根据比较的结果转移JB(或JNAE,JC)格式:同上JNB(或JAE,JNC)格式:同上JBE(或JNA)(Jump if below or equal,or not above) 低于或等于,或不高于则转移格式:JBE(或JNA) OPR测试条件:CFVZF=1JNBE(或JA)(Jump if not below or equal,or above) 不低于或等于,或者高于则转移格式:JNBE(或JA) OPR测试条件:CFVZF=03)比较两个带符号数,并根据比较的结果转移JL(或LNGE)(Jump if less,or not greater or equal) 小于,或者不大于或者等于则转移格式:JL(或JNGE) OPR测试条件:SFVOF=1JNL(或JGE)(Jump if not less,or greater or equal)不小于, 或者大于或者等于则转移格式:JNL(或JGE) OPR测试条件:SFVOF=0JLE(或JNG)(Jump if less or equal,or not greater) 小于或等于,或者不大于则转移格式:JLE(或JNG) OPR测试条件:(SFVOF)VZF=1JNLE(或JG)(Jump if not less or equal,or greater) 不小于或等于,或者大于则转移格式:JNLE(或JG) OPR测试条件:(SFVOF)VZF=04)测试CX 的值为0 则转移指令JCXZ(Jump if CX register is zero) CX 寄存器的内容为零则转移格式:JCXZ OPR测试条件:(CX)=0注:条件转移全为8 位短跳!3>循环控制指令(短转移)LOOP CX 不为零时循环.格式: LOOP OPR测试条件:(CX)<>0LOOPE/LOOPZ CX 不为零且标志Z=1 时循环.格式: LOOPZ(或LOOPE) OPR测试条件:(CX)<>0 且ZF=1LOOPNE/LOOPNZ CX 不为零且标志Z=0 时循环.格式: LOOPNZ(或LOOPNE) OPR测试条件:(CX)<>0 且ZF=0这三条指令的步骤是:1)(CX)<-(CX)-12)检查是否满足测试条件,如满足则(IP)<-(IP)+D8 的符号扩充.JCXZ CX 为零时转移.JECXZ ECX 为零时转移.4>子程序CALL 调用指令RET 返回指令5>中断指令INT 中断指令格式: INT TYPE或INT执行的操作: (SP)<-(SP)-2 ((SP)+1,(SP))<-(PSW)(SP)<-(SP)-2 ((SP)+1,(SP))<-(CS)(SP)<-(SP)-2 ((SP)+1,(SP))<-(IP)(IP)<-(TYPE*4) (CS)<-(TYPE*4+2)INTO 溢出中断执行的操作:若OF=1 则:(SP)<-(SP)-2 ((SP)+1,(SP))<-(PSW)(SP)<-(SP)-2 ((SP)+1,(SP))<-(CS)(SP)<-(SP)-2 ((SP)+1,(SP))<-(IP)(IP)<-(10H) (CS)<-(12H)IRET 中断返回格式: IRET执行的操作: (IP)<-((SP)+1,(SP))(SP)<-(SP)+2(CS)<-((SP)+1,(SP))(SP)<-(SP)+2(PSW)<-((SP)+1,(SP))(SP)<-(SP)+2六、处理器控制指令1.标志处理指令CLC 进位位置0 指令(Clear carry)CF<-0CMC 进位位求反指令(Complement carry)CF<-CFSTC 进位位置1 指令(Set carry)CF<-1CLD 方向标志置0 指令(Clear direction)DF<-0STD 方向标志置1 指令(Set direction)DF<-1CLI 中断标志置0 指令(Clear interrupt)IF<-0STI 中断标志置1 指令(Set interrupt)IF<-02.其他处理机控制指令NOP 无操作指令该指令不执行任何操作,其机器码占有一个字节,在调试程序时往往用这条指令占有一定的存储单元,以便在正式运行时用其他指令取代.HLT 停机指令该指令可使机器暂停工作,使处理机处于停机状态以便等待一次外部中断到来,中断结束后可继续执行下面的程序.WAIT 等待指令该指令使处理机处于空转状态,它也可以用来等待外部中断的发生,但中断结束后仍返回WAIT 指令继续德行.ESC 换码指令格式ESC mem其中mem 指出一个存储单元,ESC 指令把该存储单元的内容送到数据总线去.当然ESC 指令不允许使用立即数和寄存器寻址方式.这条指令在使用协处理机(Coprocessor)执行某些操作时,可从存储器指得指令或操作数.协处理机(如8087)则是为了提高速度而可以选配的硬件.LOCK 封锁指令该指令是一种前缀,它可与其他指令联合,用来维持总线的锁存信号直到与其联合的指令执行完为止.当CPU 与其他处理机协同工作时,该指令可避免破坏有用信息.七、伪指令DW 定义字(2 字节).PROC 定义过程.ENDP 过程结束.SEGMENT 定义段.ASSUME 建立段寄存器寻址.ENDS 段结束.END 程序结束.。
8086汇编语言指令表(按字母顺序)

2. 示例: (AL)=18H,(BL)=06H
ADD AL,BL ; (AL)<--(AL)+(BL) ; (AL)=1EH
DAA ; (AL)
DAS
组合十进制减法调整指令 DAS(Decimal Adjust for Subtraction)
则(AL)<--(AL)-6,(AH)<--(AH)-1,CF<--AF,(AL)<--(AL) and 0FH,
否则(AL)<--(AL) and 0FH
ADC
带进位加法指令 ADC(Addition Carry)
格式: ADC OPRD1,OPRD2
功能: OPRD1<--OPRD1 + OPRD2 + CF
DAA
组合的十进制加法调整指令 DAA(Decimal Adjust for Addition)
格式: DAA
功能: 对AL中的两个组合进制数相加的结果进行调整,调整结果仍放在AL中,进位标志放在CF中.
说明:
1. 调整操作如下
(1) 若(AL) and 0FH>9 或 AF=1,则(AL)<--(AL)+6,AF<--1,对低四位的调整.
格式: DAS
功能: 对两个组合十进制数相减后存于AL中的结果进行调整,调整后产生一个组合的十进制数且仍存于AL中.
说明:
调整操作
若(AL) and 0FH > 9 或 AF=1,则(AL)<--(AL)-6,AF=1
若(AL) and 0F0H > 90H 或 CF=1,则(AL)<--(AL)-60,CF=1
汇编语言源程序,实现10个有符号字型整数键盘输入,然后按反序输出所输入的10个有符

汇编语言源程序,实现10个有符号字型整数键盘输入,然后按反序输出所输入的10个有符号字型整数。
引言:汇编语言是一种低级机器语言,用于编写计算机程序。
它直接操作计算机硬件,具有高效性和灵活性。
本文将介绍如何使用汇编语言编写一个程序,实现键盘输入10个有符号整数,并按反序输出这些整数。
正文:1. 输入模块1.1 初始化键盘输入在汇编语言中,我们可以使用BIOS中断来初始化键盘输入。
通过调用INT 16h中断,我们可以设置键盘输入的模式和功能。
在本例中,我们将设置键盘输入模式为扫描码模式,并启用键盘中断。
1.2 读取键盘输入使用INT 16h中断的另一个功能来读取键盘输入。
通过调用INT 16h中断的功能号为0h的子功能,我们可以从键盘缓冲区中读取一个字符。
我们可以使用循环来读取10个字符,并将它们存储在内存中的一个数组中。
1.3 转换字符为整数由于键盘输入的字符是ASCII码,我们需要将它们转换为整数。
在汇编语言中,可以使用SUB指令将字符的ASCII码值减去字符'0'的ASCII码值,从而得到整数值。
2. 反序输出模块2.1 初始化输出与键盘输入类似,我们可以使用BIOS中断来初始化屏幕输出。
通过调用INT 10h中断,我们可以设置屏幕输出的模式和功能。
在本例中,我们将设置屏幕输出模式为文本模式,并清空屏幕。
2.2 输出整数我们可以使用INT 10h中断的功能号为0Eh的子功能来在屏幕上输出字符。
通过循环,我们可以从存储整数的数组中读取整数,并将其转换为字符后输出。
2.3 反序输出为了按反序输出整数,我们可以使用两个指针,一个指向数组的开头,另一个指向数组的末尾。
通过交换两个指针所指向的元素,我们可以实现反序输出。
总结:通过使用汇编语言编写的程序,我们可以实现键盘输入10个有符号整数,并按反序输出这些整数。
通过初始化键盘输入和屏幕输出,以及使用循环和指针操作,我们可以实现这个功能。
排序

实验一、用8086/8088汇编语言进行数据排序一、实验目的:1、熟悉EMU8086集成开发环境的使用。
2、通过编程、上机调试,进一步理解汇编语言的设计思路与执行过程。
3、熟悉INT 21H中断调用。
4、掌握数据排序的常用算法,利用汇编语言实现数据排序。
5、巩固理论知识,锻炼动手编程。
二、实验内容:1、在TABLE1开始的内存单元中,预先存储100个有符号字类型的数值。
2、编写代码、将TABLE1中的100个数值,按照从大到小的排序,放在TABLE2开始的内存单元中。
3、将TABLE2中的数字,顺序输出在屏幕上。
4、查看TABLE1开始的内存的100个数值。
5、查看TABLE2开始的内存的100个数值。
三、设计思路:1、自定义一个display函数,用来往屏幕上显示特定的字符。
2、定义一个data段,用来存储固定的字符。
3、定义一个code段,当做主程序。
4、所用的方法是冒泡排序法5、主程序中第一步先获取键盘输入。
6、主程序中第二步将键盘输入的数存储到内存中。
7、主程序中第三步用[基址+变址]方法进行冒泡排序。
8、主程序中第四步将排序好后新的数组从内存中取出,并回显到屏幕上。
四、排序算法:1、冒泡排序:(1)比较相邻的两个元素,如果第二个比第一个大,则交换这两个值。
(2)对每一对相邻元素做相同的工作,从开始第一对到结尾的最后一对,这样最后的元素应该会是最大的数。
(3)针对所有的元素重复以上的步骤,除去最后一个。
(实际过程中是最后一个值和后面的一个空值进行比较)(4)重复(1)~(3),直至排序完成。
2、选择排序:(1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
(2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
(3)重复(1)~(2)过程,直至排序完成。
3、插入排序:(1)构建有序数列。
(2)对于未排序的数据,在已排序的数列中从后向前扫描。
(3)找到相对应的位置后插入。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
提示:在做实验时,我们要自己将代码区和数据区分开,因为8086上没有软件帮我们完成这个任务。
MOV R0,#218 //之所以选择208这个大点的地址,是因为避免将数据写到了代码区LOOP1:IN //将数据读入A
ADD A,#128 //将补码转换为其对应的移码,因为补码本身参与加减不能比较出大
//小,而移码就是将其真值在数轴上平移了2的n次方MOV @R0,A
MOV A,R0
sub a,#1
SUB A,#208 //判断有没有输入完10个数
JZ LOOP2 //输入完数据,跳转
ADD A,#208
MOV R0,A
JMP LOOP1//没有输入完,就跳回接着输入
LOOP2:MOV R0,#9 //9轮循环比较就可以排完序
MOV R1,#209
MOV R2,#210
LOOP4:MOV A,@R2
SUBC A,@R1
JC LOOP3 //若210地址指向的单元中的数比209地址指向的单元中的小,则交
//换
LOOP5:MOV A,R2
ADD A,#1
SUBC A,#219 //判断此轮有没有比较完
JZ LOOP6 //若比较完,就跳到LOOP6,否则继续比较
ADD A,#219
MOV R2,A
JMP LOOP4
LOOP3:MOV A,@R1
MOV 208,A
MOV A,@R2
MOV @R1,A
MOV A,208
MOV @R2,A
JMP LOOP5 //交换完了就跳回
LOOP6: MOV A,R1
ADD A,#1
MOV R1,A
ADD A,#1
MOV R2,A //让R2始终指向的是R1下一个单元
MOV A,R0
SUB A,#1
JZ LOOP7 //判断9轮比较有没有完成,若完成,跳LOOP7,否则,继续比
//较
MOV R0,A
JMP LOOP4
LOOP7: MOV R0,#218
LOOP9: MOV A,@R0 //下面这一段代码就是将数还原,因为原来我们是那人家的移码
//形式来比较的,相信下面这一段就不用多讲了吧ADD A,#128
MOV @R0,A
MOV A,R0
sub a,#1
SUB A,#208
JZ LOOP8
ADD A,#208
MOV R0,A
JMP LOOP9
LOOP8:END。