• 跟我一起写个虚拟机 .Net 7(三)- 安装LC-3 模拟器和编译器


    LC-3(Little Computer 3) 是一门教学用的虚拟计算机模型,主要是为了方便学生了解简单化的计算机结构。

    主要想学习《计算机系统概论》上的案例,基本都是通过LC-3 模拟器和LC-3编译器来的,所以,把安装的方式学习一下。

    这两个软件偏向于在Unix中安装,我这边没有那个环境,所以,我会把编译器安装在Ubuntu中,模拟器采用windows版的安装到本地。

    官网地址

    https://highered.mheducation.com/sites/0072467509/student_view0/lc-3_simulator_lab_manual.html

    下载 C 3 Simulator Windows Version 3.01 (385.0K)

    这个主要是模拟器,windows直接运行

    htps://highered.mheducation.com/sites/dl/free/0072467509/104652/LC301.exe

    下载后,双击运行

    进入到安装目录

    Simulate.exe 模拟器


    模拟器只能打开.obj目标文件

    LC3Edit.exe 编译器

    可以通过以下三种方式(二进制,16进制,汇编)写代码逻辑,输出目标文件等结构


    用汇编来写还是相对来讲简单的,写完之后,点击3,汇编的箭头按钮,就会保存在一个文件里,输出以下文件,当然,报错的情况下,它会提示错误。

    1. 123.asm 它是汇编文件本身
    2. 123.bin 它是二进制文件
    3. 123.hex 它是十六进制的文件
    4. 123.lst 它是程序的列表文件
    5. 123.sym 它是创建汇编的符号表
    6. 123.obj 目标文件,需要Simulate.exe 模拟器打开

    下载 C to LC-3 Compiler (369.0K)

    https://highered.mheducation.com/sites/dl/free/0072467509/104652/lcc.zip

    解压后如下:


    大概有这些东西

    根据README描述,需要gcc 和 wish 和 flex ,我这边直接安装flex就会安装gcc了。

    然后在当前目录执行命令

    chmod +x configure
    sudo apt install flex 
    ./configure
    
    • 1
    • 2
    • 3

    然后,就会显示下边这个,就成功make了,然后,开始执行安装命令

    make
    make install
    
    • 1
    • 2

    make 执行完

    make install 执行完

    这个时候就会在当前文件夹下,新增一个install的文件夹,其中 lcc就是编译器了

    可以通过 lcc 直接执行来看看帮助信息

    ./lcc
    
    • 1

    可以看到命令还是挺全的

    编译C语言文件

    cd 到目标路径下

    cd /root/lcc-1.3/install/
    
    • 1

    然后创建一个c语言的程序,如下

    int main()
    {
        int a=1;
        int b=2;
        int c=a+b;
        printf("data:%d",c);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    执行编译命令,就会生成a.asm文件,竟然有4KB大小

    lcc main.c
    
    • 1

    最后可以看到很长的lc3的汇编(a.asm)

    .Orig x3000
    INIT_CODE
    LEA R6, #-1
    ADD R5, R6, #0
    ADD R6, R6, R6
    ADD R6, R6, R6
    ADD R6, R6, R5
    ADD R6, R6, #-1
    ADD R5, R5, R5
    ADD R5, R6, #0
    LD R4, GLOBAL_DATA_POINTER
    LD R7, GLOBAL_MAIN_POINTER
    jsrr R7
    HALT
    
    GLOBAL_DATA_POINTER .FILL GLOBAL_DATA_START
    GLOBAL_MAIN_POINTER .FILL main
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    main
    ADD R6, R6, #-2
    STR R7, R6, #0
    ADD R6, R6, #-1
    STR R5, R6, #0
    ADD R5, R6, #-1
    
    ADD R6, R6, #-3
    ADD R7, R4, #12
    ldr R7, R7, #0
    str R7, R5, #0
    ADD R7, R4, #11
    ldr R7, R7, #0
    str R7, R5, #-1
    ldr R7, R5, #0
    ldr R3, R5, #-1
    add R7, R7, R3
    str R7, R5, #-2
    ldr R7, R5, #-2
    ADD R6, R6, #-1
    STR R7, R6, #0
    ADD R7, R4, #3
    ADD R6, R6, #-1
    STR R7, R6, #0
    ADD R0, R4, #1
    LDR R0, R0, #0
    jsrr R0
    LDR R7, R6, #0
    ADD R6, R6, #1
    ADD R7, R4, #2
    ldr R7, R7, #0
    lc3_L1_main
    STR R7, R5, #3
    ADD R6, R5, #1
    LDR R5, R6, #0
    ADD R6, R6, #1
    LDR R7, R6, #0
    ADD R6, R6, #1
    RET
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;	void printf(const char *format, ...)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    PRINTF_PERCENT .FILL -37
    PRINTF_C .FILL -99
    PRINTF_D .FILL -100
    PRINTF_S .FILL -115
    PRINTF_B .FILL -98
    PRINTF_O .FILL -111
    PRINTF_X .FILL -120
    PRINTF_ASCII .FILL 48 		;postive ascii value of '0'
    .FILL 49
    .FILL 50
    .FILL 51
    .FILL 52
    .FILL 53
    .FILL 54
    .FILL 55
    .FILL 56
    .FILL 57
    .FILL 65        ;A
    .FILL 66
    .FILL 67
    .FILL 68
    .FILL 69
    .FILL 70
    PRINTF_MINUS .FILL 45  
    PRINTF_BUF .BLKW 18
     
    
    lc3_printf
    ADD R6, R6, #-2
    STR R7, R6, #0		;return address
    ADD R6, R6, #-1
    STR R5, R6, #0
    ADD R5, R6, #-1
    
    ADD R6, R6, #-1
    STR R4, R6, #0
    
    ADD R5, R5, #4		;cheating with the bp (no longer bp)
    LDR R4, R5, #0		;got addr of format string
    
    
    PRINTF_LOOP	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    LDR R0, R4, #0
    
    ADD R0, R0, #0		;End of string? (0x0000)
    BRz PRINTF_DONE
    
    ADD R2, R0, #0
    LD R1, PRINTF_PERCENT
    ADD R2, R2, R1
    BRnp PRINTF_CHAR		
    
    ADD R4, R4, #1
    LDR R0, R4, #0
    ;is it %c?
    ADD R2, R0, #0
    LD R3, PRINTF_C
    ADD R2, R2, R3
    BRnp PRINTF_CHECKSTR
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c
    ADD R5, R5, #1
    LDR R0, R5, #0
    
    PRINTF_CHAR
    OUT
    
    ADD R4, R4, #1
    BRnzp PRINTF_LOOP
    
    PRINTF_CHECKSTR
    ;is it %s?
    ADD R2, R0, #0
    LD R7, PRINTF_S
    ADD R2, R2, R7
    BRnp PRINTF_CHECKDEC		
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%s
    
    ADD R5, R5, #1
    LDR R0, R5, #0
    PUTS
    
    ADD R4, R4, #1
    BRnzp PRINTF_LOOP
    
    PRINTF_CHECKDEC
    ;is it %d?
    ADD R2, R0, #0
    LD R7, PRINTF_D
    ADD R2, R2, R7
    ;BRnp PRINTF_ERROR
    BRnp PRINTF_CHECKHEX
    
    AND R2, R2, #0
    ADD R2, R2, #-10		;going to divide by 10 by using sub loop
    BRnzp PRINTF_NUM
    
    PRINTF_CHECKHEX
    
    ADD R2, R0, #0
    LD R7, PRINTF_X
    ADD R2, R2, R7
    BRnp PRINTF_CHECKOCT
    
    AND R2, R2, #0
    ADD R2, R2, #-16		;going to divide by 10 by using sub loop
    BRnzp PRINTF_NUM
    
    PRINTF_CHECKOCT
    
    ADD R2, R0, #0
    LD R7, PRINTF_O
    ADD R2, R2, R7
    BRnp PRINTF_CHECKBIN
    
    AND R2, R2, #0
    ADD R2, R2, #-8		;going to divide by 10 by using sub loop
    BRnzp PRINTF_NUM
    
    PRINTF_CHECKBIN
    
    ADD R2, R0, #0
    LD R7, PRINTF_B
    ADD R2, R2, R7
    BRnp PRINTF_ERROR
    
    AND R2, R2, #0
    ADD R2, R2, #-2		;going to divide by 10 by using sub loop
    ;BRnzp PRINTF_NUM
    
    
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d
    PRINTF_NUM
    
    LEA R7, PRINTF_BUF
    ADD R7, R7, #15 
    ADD R7, R7, #1 
    
    ;AND R2, R2, #0
    ;ADD R2, R2, #-10		;going to divide by 10 by using sub loop
    
    ADD R5, R5, #1			;acquire the binary number
    LDR R0, R5, #0
    
    ADD R0, R0, #0
    BRzp PRINTF_DECPOS 
    
    NOT R0, R0				;make num positive for sub loop
    ADD R0, R0, #1
    
    PRINTF_DECPOS
    
    AND R3, R3, #0
    ADD R3, R3, #-1
    
    PRINTF_DIVLOOP
    ADD R3, R3, #1			;num/10 
    ADD R0, R0, R2			;R0 = num % 10 - 10
    BRzp PRINTF_DIVLOOP
    
    ADD R3, R3, #0
    BRz PRINTF_LASTDIGIT
    
    ;LD R1, PRINTF_ASCII
    ;ADD R1, R1, R0
    ;NOT R2, R2
    ;ADD R1, R1, R2 
    ;ADD R1, R1, #1
    ;NOT R2, R2
    ;;;;;ADD R1, R1, #10
    ;STR R1, R7, #0
    ;ADD R7, R7, #-1			;stored ascii value of one digit
    
    LEA R1, PRINTF_ASCII
    ADD R1, R1, R0
    NOT R2, R2
    ADD R1, R1, R2 
    ADD R1, R1, #1
    NOT R2, R2
    LDR R1, R1, #0
    STR R1, R7, #0
    ADD R7, R7, #-1			;stored ascii value of one digit
    
    ADD R0, R3, #0			;num/10
    
    BRnzp PRINTF_DECPOS
    
    PRINTF_LASTDIGIT
    
    ;LD R1, PRINTF_ASCII
    ;ADD R1, R1, R0
    ;ADD R1, R1, #10
    ;STR R1, R7, #0
    
    LEA R1, PRINTF_ASCII
    ADD R1, R1, R0
    NOT R2, R2
    ADD R1, R1, R2 
    ADD R1, R1, #1
    NOT R2, R2
    LDR R1, R1, #0
    STR R1, R7, #0			;stored ascii value of highest order digit
    
    LDR R0, R5, #0
    ADD R0, R0, #0
    BRzp PRINTF_DECSTRING
    
    LD R0, PRINTF_MINUS		;num was negative
    ADD R7, R7, #-1
    STR R0, R7, #0			;stored ascii value negative sign
    
    PRINTF_DECSTRING		;print the calculated string
    ADD R0, R7, #0
    PUTS
    
    ADD R4, R4, #1
    BRnzp PRINTF_LOOP
    
    PRINTF_ERROR
    PRINTF_DONE
    
    LDR R4, R6, #0		;restore R4
    ADD R6, R6, #1
    
    LDR R5, R6, #0		;restore bp
    ADD R6, R6, #1
    
    LDR R7, R6, #0		;restore ret addr
    ADD R6, R6, #1
    
    RET
    
    GLOBAL_DATA_START
    L1_main .FILL lc3_L1_main
    printf .FILL lc3_printf
    L5_main .FILL #0
    L4_main .STRINGZ "data:%d"
    L3_main .FILL #2
    L2_main .FILL #1
    .END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304

    终于看到完整能输出lc3汇编的方式了。

    错误情况处理

    //Cannot locate make binary. 那就是缺少 make 库
    sudo apt install make -y
    
    • 1
    • 2

    直接通过LC-3编辑器执行这个 a.asm 文件,会发现有这样的错误


    目前查找的资料是说它未发现这些符号。

    可执行的汇编

    .ORIG		X3000
    		AND	R0,R0,#0;
    		AND	R1,R1,#0;
    		AND	R2,R2,#0;
    		AND	R3,R3,#0;
    		AND 	R4,R4,#0;
    		AND 	R5,R5,#0;
    		AND 	R6,R6,#0;
    		AND	R7,R7,#0;初始化寄存器
    
    		ADD	R5,R5,#15;
    		ADD	R5,R5,#1;外层循环16次
    		LD	R2,SCORE2;指向存成绩空间
    OUTLOOP		ADD	R6,R6,#15;内层循环15次
    		LD	R3,SCORE;指针指向成绩	
    		LDR	R0,R3,#0;假设第一位为最大值,存入R0
    		NOT	R0,R0;
    		ADD	R0,R0,#1;R0最大值求补数
    LOOP1		ADD	R3,R3,#1;指针指向下一个数字	
    		LDR	R1,R3,#0;R1存入对比数字
    		ADD	R4,R0,R1;R1>R0,将R0设为新的最大值R1,否则继续
    		BRp	SWAP;将最大值设置为当前查询数
    		ADD	R6,R6,#-1;
    		BRz	GOOUT;内层循环结束,跳出二层循环
    		BRnzp	LOOP1;
    SWAP		AND	R0,R0,#0;
    		NOT	R1,R1;
    		ADD	R1,R1,#1;R1最大值求补数
    		ADD	R0,R0,R1;	
    		ADD	R6,R6,#-1;
    		BRz	GOOUT;内层循环结束,跳出二层循环	
    		BRnzp	LOOP1;
    GOOUT		LD	R7,SCORE;遍历成绩表,与最大值相等的数据设置为-1。
    LOOP2		LDR	R1,R7,#0;
    		ADD	R1,R1,R0;
    		BRz	SET;
    		ADD	R7,R7,#1;
    		ADD	R1,R1,#0;
    		BRnp	LOOP2;
    SET		LD	R1,MINUS1;删除当前轮最大值(设置为-1)
    		STR	R1,R7,#0;
    		NOT	R0,R0;
    		ADD	R0,R0,#1;R0为当前轮最大值
    		ADD	R2,R2,#1;
    		STR	R0,R2,#0;
    		ADD	R7,R7,#1;
    		ADD	R5,R5,#-1;
    		BRp	OUTLOOP;	
    		BRZ	END;
    
    
    END		AND	R0,R0,#0;
    		AND	R1,R1,#0;
    		AND	R2,R2,#0;
    		AND	R3,R3,#0;
    		AND 	R4,R4,#0;
    		AND 	R5,R5,#0;
    		AND 	R6,R6,#0;
    		AND	R7,R7,#0;初始化寄存器
    
    
    	
    		ADD	R1,R1,#4;遍历1-4名成绩,判断是否为A
    		LD	R2,SCORE2;将指针指向第一名成绩
    		ADD	R2,R2,#1;
    		LD	R6,EIGHTYFIVE;R6存储-85
    
    LOOP		LDR	R0,R2,#0;R0存储当前查询成绩
    		ADD	R4,R0,R6;检查当前成绩是否大于绝对分数85分,若大于R5=1,小于R5=0
    		BRzp	OVERABSOLUTE;
    		AND	R5,R5,#0;
    		BRnzp	NEXT2;
    OVERABSOLUTE	AND	R5,R5,#0;
    		ADD	R5,R5,#1;
    NEXT2		ADD	R5,R5,#-1;R5等于1,条件满足,为A,等于0,条件不满足,进行下一轮测试
    		BRn	NO;
    YES		ADD	R7,R7,#1;R7记录A等人数,加一
    		ADD	R2,R2,#1;指针指向下一位成绩
    		ADD	R1,R1,#-1;循环次数减一
    		BRp	LOOP;
    		BRz	END1;
    NO		ADD	R2,R2,#1;指针指向下一位成绩
    		ADD	R1,R1,#-1;循环次数减一
    		BRp	LOOP;
    		BRz	END1;
    END1		STI	R7,GRADEA;将R7数据存入x4100
    
    
    
    		LD	R2,SCORE2;
    		ADD	R2,R2,#1;
    		ADD	R2,R2,R7;将指针指向第N+1名成绩
    		NOT	R7,R7;
    		ADD	R7,R7,#1;
    		ADD	R7,R7,#8;
    		AND	R1,R1,#0;
    		ADD	R1,R1,R7;遍历N+1-8名成绩,判断是否为B,循环次数8-n存入R1		
    		AND	R6,R6,#0;
    		LD	R6,SEVENTYFIVE;R6存储-75
    		AND	R7,R7,#0;人数统计归零
    
    LOOP0		LDR	R0,R2,#0;R0存储当前查询成绩
    		ADD	R4,R0,R6;检查当前成绩是否大于绝对分数75分,若大于R5=1,小于R5=0
    		BRzp	OVERABSOLUTE1;
    		AND	R5,R5,#0;
    		BRnzp	NO1;
    OVERABSOLUTE1	AND	R5,R5,#0;
    		ADD	R5,R5,#1;
    NEXT4		ADD	R5,R5,#-1;R5等于1,条件满足,为B,等于0,条件不满足,默认为C
    		BRn	NO1;
    YES1		ADD	R7,R7,#1;R7记录A等人数,加一
    		ADD	R2,R2,#1;指针指向下一位成绩
    		ADD	R1,R1,#-1;循环次数减一
    		BRp	LOOP0;
    		BRz	END2;
    NO1		ADD	R2,R2,#1;指针指向下一位成绩
    		ADD	R1,R1,#-1;循环次数减一
    		BRp	LOOP0;
    		BRz	END2;
    END2		STI	R7,GRADEB;将R7数据存入x4101
     
    HALT;
    SCORE		.fill	x3200;
    SCORE2		.FILL	X3FFF;
    GRADEA		.fill	x4100;
    GRADEB		.fill	x4101;
    EIGHTYFIVE	.fill	#-85;
    SEVENTYFIVE	.fill	#-75;
    MINUS1		.FILL	#-1;
    .END;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130

    可以先执行这个汇编和借用其中的方式方法。我大致看了,它没有使用直接编译的方式,而是直接手写汇编实现。

    里面很多C语言里的函数都找不到标签,所以,相当于一些函数类的,无法搞定。对于学习也是够的了。

    总结

    至此 LC-3 模拟器和编辑器以及编译器都安装完了,还挺麻烦的,找了很多资料,相对而言,还是有点老了。

    引用

    参考了《深圳大学CS本科课程资源共享》,感谢大佬的作业。

    https://github.com/Alex-Shen1121/SZU_Learning_Resource

  • 相关阅读:
    npm--加快下载速度的方法
    spring security - 快速整合 springboot
    app查看 证书公钥和md5
    排序算法基础篇
    C++ 信号处理
    纷享销客数字化营销(一):企业专属微站和员工智能名片
    软件提示vcruntime140_1.dll丢失的解决方法,以及丢失的原因总结
    网络通信 三要素
    笔试强训48天——day23
    【信号调理】精密检波电路和PCB示例
  • 原文地址:https://blog.csdn.net/kesshei/article/details/133935936