计组--复杂模型机--冒泡算法微指令程序

本文详细介绍了使用C++实现冒泡排序算法的过程,并提供了对应的汇编指令和微指令示例,展示了从编程语言到底层硬件操作的转换过程。
摘要由CSDN通过智能技术生成

绪论:分享一下自己写的代码。仅供参考!!!

1.实验设备

   唐都实验箱

2.冒泡算法

C++代码:

//定义一个标志位,用于判定元素之间是否进行了交换
        boolean flag = false;
 
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    //进入这个if分支里边,则说明有元素进行了交换
                    //所以将flag=true
                    flag = true;
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            
            //在进行完一轮的排序之后,判断本轮是否发生了元素之间的交换
            //如果没有发生交换,说明数组已经是有序的了,则直接结束排序
            if (!flag) {
                break;
            } else {
                //如果发生了交换,那么在下一轮排序之前将flag再次置为false
                //以便记录下一轮排序的时候是否会发生交换
                flag = false;
            }
        }

汇编指令格式:(测试的时候修改了一些代码,找不到修改的代码了。都是小问题,调试的时候很容易发现)

;test IN 03H   A[0] = 8, A[1] = 1, A[2] = 5   1 8 5  1 5 8
START:       
IN   R1,00H    ;R1 = 03
STA  R1,EEH    ;循环显示次数
STA  R1,EAH    ;存R1进EAH

;LOOP_I
LDI  R0,01H    ;R0 = 01H
LAD  R1,EAH    ;R1 = 3   R1 = 2
SUB  R1,R0     ;R1 = 2   R1 = 1
STA  R1,EAH    ;EAH = 2  1
BZC  DISPLAY
STA  R1,EBH    ;EBH = 2  EB = 1
LAD  R2,ECH    ;两两比较每次内循环都是从0开始
STA  R0,F2     ;flag = 1 每次内循环开始前都要初始化flag

;LOOP_J
LAD  R0,[RI],00H   ;A[J]   J = 1
SAT  R0,F1H    ;存A[J],SUB会修改R0
LAD  R1,[RI],01H   ;A[J+1]
SAT  R2,F0H    ;存A[J]的地址    
INC  R2;       ;地址指针+1  E2
SUB  R0,R1     ;R0 = A[J] - A[J+1]
BZC  NEXT1     ;A[J] < A[J+1],跳过交换  

;CHANGE        ;A[J] > A[J+1] 需要交换
LAD  R0,F1H    ;读出a[J]
STA  R0,[RI],00H   ;A[J] -> A[J+1]
LAD  R2,F0H    ;读出RI
STA  R1,[RI],00H   ;A[J+1] -> A[J]
INC  R2            ;保持R2之前的值
;交换后需要修改flag的值为2
LDI  R0,01H
INC  R0       ;R0 = 2
STA  R0,F2    ;flag = 2

;NEXT1:
LDI  R0,01H   ;之前R0被修改了,需要重新赋值为01H
LAD  R1,EB    ;R1 = 2    R1 = 1
SUB  R1,R0    ;R1 = 1    R1 = 0
STA  R1,EBH   ;EBH = 1   EBH = 0
BZC  Boolean_flag
JMP  LOPP_J

;Boolean_flag
LAD  R3,F2 ;flag
SUB  R3,R0
BZC  DISPLAY
JMP  LOOP_I

;DISPLAY
LDI   R0,01H
LAD  R2,ECH   ;取数据基址E0H(存在EC里面)
LAD  R1,EEH   ;需要显示的元素个数

;LOOP1:
LAD  R3,[RI],00H    ;取数组数据进R3
OUT  40H,R3   ;在40H端口输出
INC  R2;      ;数组下标 + 1
SUB  R1,R0    ;输出循环次数减1
BZC  ENDS
JMP LOOP1

ENDS:
HLT


;a[10]={8,1,5,9,3,4,7,6,2,10}
  $P E0 08    ; 数据
  $P E1 01
  $P E2 05
  $P E3 09
  $P E4 03
  $P E5 04
  $P E6 07
  $P E7 06
  $P E8 02
  $P E9 10
  $P EA 00  ;存外层循环次数
  $P EB 00  ;存内层循环次数
  $P EC E0  ;存外层R2  数据地址E0H开始,R2作为RI指针  寻址方式[RI]
  $P ED E1  ;存内层R2
  $P EE 00  ;记录显示元素个数length
  $P EF 05  ;显示延时循环次数
  $P F0 00  ;数据交换的缓存区存RI未加1前的值
  $P F1 00  ;数据交换的缓存区 存a[i]
  $P F2 00  ;记录是否有交换,无交换设为1(已经有序),有交换设为2,每次内循环开始前都要初始化为1。

微指令格式:

;test IN 03H   A[0] = 8, A[1] = 1, A[2] = 5   1 8 5  1 5 8
;START:
$P 00  21;IN   R1,00H    ;R1 = 03
$P 01  00  
$P 02  D1;STA  R1,EEH    ;循环显示次数
$P 03  EE
$P 04  D1;STA  R1,EAH    ;存R1进EAH
$P 05  EA  

;LOOP_I
$P 06  60;LDI  R0,01H    ;R0 = 01H
$P 07  01
$P 08  C1;LAD  R1,EAH    ;R1 = 3   R1 = 2
$P 09  EA
$P 0A  81;SUB  R1,R0     ;R1 = 2   R1 = 1
$P 0B  D1;STA  R1,EAH    ;EAH = 2  1
$P 0C  EA
$P 0D  F0;BZC  DISPLAY
$P 0E  41
$P 0F  D1;STA  R1,EBH    ;EBH = 2  EB = 1
$P 10  EB
$P 11  C2;LAD  R2,ECH    ;R2 = E = E0,两两比较每次内循环都是从0开始
$P 12  EC
$P 13  D0;STA  R0,F2     ;flag = 1 每次内循环开始前都要初始化flag
$P 14  F2

;LOOP_J
$P 15  C8;LAD  R0,[RI],00H   ;A[J]   J = 1
$P 16  00
$P 17  D0;SAT  R0,F1H    ;存A[J],SUB会修改R0
$P 18  F1
$P 19  C9;LAD  R1,[RI],01H   ;A[J+1]
$P 1A  01
$P 1B  D2;SAT  R2,F0H    ;存A[J]的地址
$P 1C  F0    
$P 1D  72;INC  R2;       ;地址指针+1  E2
$P 1E  84;SUB  R0,R1     ;R0 = A[J] - A[J+1]
$P 1F  F0;BZC  NEXT1     ;A[J] < A[J+1],跳过交换
$P 20  2F  

;CHANGE        ;A[J] > A[J+1] 需要交换
$P 21  C0;LAD  R0,F1H    ;读出a[J]
$P 22  F1
$P 23  D8;STA  R0,[RI],00H   ;A[J] -> A[J+1]
$P 24  00
$P 25  C2;LAD  R2,F0H    ;读出RI
$P 26  F0
$P 27  D9;STA  R1,[RI],00H   ;A[J+1] -> A[J]
$P 28  00
$P 29  72;INC  R2            ;保持R2之前的值
;交换后需要修改flag的值为2
$P 2A  60;LDI  R0,01H
$P 2B  01
$P 2C  70;INC  R0       ;R0 = 2
$P 2D  D0;STA  R0,F2    ;flag = 2
$P 2E  F2;

;NEXT1:
$P 2F  60;LDI  R0,01H   ;之前R0被修改了,需要重新赋值为01H
$P 30  01
$P 31  C1;LAD  R1,EB    ;R1 = 2    R1 = 1
$P 32  EB
$P 33  81;SUB  R1,R0    ;R1 = 1    R1 = 0
$P 34  D1;STA  R1,EBH   ;EBH = 1   EBH = 0
$P 35  EB
$P 36  F0;BZC  Boolean_flag
$P 37  3A
$P 38  E0;JMP  LOOP_J
$P 39  15

;Boolean_flag
$P 3A  C3;LAD  R3,F2 ;flag
$P 3B  F2
$P 3C  83;SUB  R3,R0
$P 3D  F0;BZC  DISPLAY
$P 3E   41
$P 3F  E0;JMP  LOOP_I
$P 40  06


;DISPLAY 
$P 41  60;LDI   R0,01H
$P 42  01
$P 43  C2;LAD  R2,ECH   ;取数据基址E0H(存在EC里面)
$P 44  EC
$P 45  C1;LAD  R1,EEH   ;需要显示的元素个数
$P 46  EE
;LOOP1:
$P 47  CB;LAD  R3,[RI],00H    ;取数组数据进R3
$P 48  00
$P 49  3C;OUT  40H,R3   ;在40H端口输出
$P 4A  40
$P 4B  72;INC  RI;      ;数组下标 + 1    E1   E2
$P 4C  81;SUB  R1,R0    ;输出循环次数减1    R1 = 1    0
$P 4D  F0;BZC  ENDS
$P 4E  51
$P 4F  E0;JMP LOOP1
$P 50  47

;ENDS:
$P 51  50;HLT


;a[10]={8,1,5,9,3,4,7,6,2,10}
  $P E0 08    ; 数据
  $P E1 01
  $P E2 05
  $P E3 09
  $P E4 03
  $P E5 04
  $P E6 07
  $P E7 06
  $P E8 02
  $P E9 10
  $P EA 00  ;存外层循环次数
  $P EB 00  ;存内层循环次数
  $P EC E0  ;存外层R2  数据地址E0H开始,R2作为RI指针  寻址方式[RI]
  $P ED E1  ;存内层R2
  $P EE 00  ;记录显示元素个数length
  $P EF 01  ;显示延时循环次数
  $P F0 00  ;数据交换的缓存区 存RI未加1前的值
  $P F1 00  ;数据交换的缓存区 存a[i]
  $P F2 00  ;记录是否有交换,无交换设为1(已经有序),有交换设为2,每次内循环开始前都要初始化为1。

; //** Start Of MicroController Data **//
  $M 00 000001    ; NOP
  $M 01 006D43    ; PC->AR, PC加1
  $M 03 107070    ; MEM->IR, P<1>
  $M 04 002405    ; RS->B
  $M 05 04B201    ; A加B->RD
  $M 06 002407    ; RS->B
  $M 07 013201    ; A与B->RD
  $M 08 106009    ; MEM->AR
  $M 09 183001    ; IO->RD
  $M 0A 106010    ; MEM->AR
  $M 0B 000001    ; NOP
  $M 0C 103001    ; MEM->RD
  $M 0D 200601    ; RD->MEM
  $M 0E 005341    ; A->PC
  $M 0F 0000CB    ; NOP, P<3>
  $M 10 280401    ; RS->IO
  $M 11 103001    ; MEM->RD
  $M 12 06B201    ; A加1->RD
  $M 13 002414    ; RS->B
  $M 14 05B201    ; A减B->RD
  $M 15 002416    ; RS->B
  $M 16 01B201    ; A或B->RD
  $M 17 002418    ; RS->B
  $M 18 02B201    ; A右环移->RD
  $M 1B 005341    ; A->PC
  $M 1C 10101D    ; MEM->A
  $M 1D 10608C    ; MEM->AR, P<2>
  $M 1E 10601F    ; MEM->AR
  $M 1F 101020    ; MEM->A
  $M 20 10608C    ; MEM->AR, P<2>
  $M 28 101029    ; MEM->A
  $M 29 00282A    ; RI->B
  $M 2A 04E22B    ; A加B->AR
  $M 2B 04928C    ; A加B->A, P<2>
  $M 2C 10102D    ; MEM->A
  $M 2D 002C2E    ; PC->B
  $M 2E 04E22F    ; A加B->AR
  $M 2F 04928C    ; A加B->A, P<2>
  $M 30 001604    ; RD->A
  $M 31 001606    ; RD->A
  $M 32 006D48    ; PC->AR, PC加1
  $M 33 006D4A    ; PC->AR, PC加1
  $M 34 003401    ; RS->RD
  $M 35 000035    ; NOP
  $M 36 006D51    ; PC->AR, PC加1
  $M 37 001612    ; RD->A
  $M 38 001613    ; RD->A
  $M 39 001615    ; RD->A
  $M 3A 001617    ; RD->A
  $M 3B 000001    ; NOP
  $M 3C 006D5C    ; PC->AR, PC加1
  $M 3D 006D5E    ; PC->AR, PC加1
  $M 3E 006D68    ; PC->AR, PC加1
  $M 3F 006D6C    ; PC->AR, PC加1
; //** End Of MicroController Data **//

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值