好文档 - 专业文书写作范文服务资料分享网站

《汇编语言程序设计》习题答案(第二版,沈美明,温冬婵,清华大学出版社)

天下 分享 时间: 加入收藏 我要投稿 点赞

汇编语言程序设计(第二版)

第二章

1、 答:直接由指令指定的I/O端口数为256个。

2、答:

3、答:字节单元:(30022H) = AB H,(30024H) = EF H 字单元: (30021H) = AB34 H,(30022H) = CDAB H。

4、答:3017:000A的存储单元的物理地址是3017AH, 3015:002A的存储单元的物理地址是3017AH, 3010:007A的存储单元的物理地址是3017AH。

5、答:该程序的第一个字的物理地址是0AAA40H。

6、答:条件标志OF、SF、ZF、CF的值依次分别为0、0、0、0。

7、答:(1)AX、BX、CX、DX、AH、AL、BH、BL、CH、CL、DH、DL、 SP、BP、DI、SI(注意:学生尽量不要用SP参与加减运算) (2)CX

(3)DX、AX、AH、AL (4)CS、DS、ES、SS (5)FLAGS (6)IP

(7)SS、SP、BP

8、答:可以用来指示存储器地址的寄存器有BX、SP、BP、DI、SI、IP、CS、DS、

ES、SS。

9、答:唯一正确的是D。

第三章

1。

.(1)立即寻址 没有 (2)直接寻址 7237H

(3)使用BX的寄存器寻址 没有 (4)使用BX的间接寻址 637DH (5)使用BX的寄存器相对寻址 0D5F0H (6) 基址变址寻址 8E18H (7)相对基址变址 004FH

Page 1 of 41

1

2。根据下列要求,写出相应的汇编指令。 (1)ADD DX,BX

(2) ADD AL,[BX][SI] (3) ADD [BX][0B2H], CX

(4) MOV AX,2A59H ADD [0524H] ,AX (5) ADD AL ,0B5H 3。

(1)寄存器间接寻址

MOV BX,OFFSET [BLOCK][0AH] MOV DX ,[BX] (2)寄存器相对寻址 MOV SI,OAH MOV DX,[BLOCK][SI]

(3)基址变址寻址 MOV BX ,BLOCK MOV SI,OAH MOV DX,[BX][SI] 4现有(DS)

=2000H,(BX)=0100H,(SI)=0002H,(20100)=12H,(20101)=34H,(20102)=56H,(20103)=78H,(21200)=2AH,(20201)=4CH,(21202)=B7H,(21203)=65H,试说明下列各条指令执行完后,AX寄存器的内容。

(1)MOV AX,1200H 1200H

(2) MOV AX,BX 0100H

(3) MOV AX,[1200] 4C2AH 注意,是字单元!! (4)MOV AX,[BX] 3412H 同上 (5)MOV 1100[BX] 4C2AH (6) MOV AX,[BX][SI] 7856H (7) MOV AX,1100[BX][SI] 65B7H 5。

(1) 7CD9H (2) 1200H (3) 6319H

6。 MOV BX,2000H LES DI ,[BX]

MOV AX, ES:DI

7。转向地址OBJ的值分别为:(1)064DH (2)0691H (3)05E0H 注意有符号数的符号位~~

8。(1) MOV AX,0ABH 立即数寻址 无物理地址 (2)MOV AX,BX 寄存器寻址 同上 (3)MOV AX,[100] 直接寻址 20100H (4)MOV AX,VAL 直接寻址 20050H (5) MOV AX,[BX] 寄存器间接寻址 20100H (6) MOV AX,ES:[BX] 直接寻址 21100H (7) MOV AX,[BP] 寄存器间接寻址 20010H

Page 2 of 41

2

(8)MOV AX,[SI] 同上 200A0H

(9) MOV AX,[BX+10] 寄存器相对寻址 20110H (10)MOV AX,VAL[BX] 同上 20150H

(11) MOV AX,[BX][SI] 基址变址寻址 201A0H

(12) MOV AX,VAL[BX][SI] 相对基相变址寻址 201F0H 9。的指令: MOV AX, [BX][0CH]

MOV ZREO ,AX

(2) 的指令: MOV AX,ARRAY[BX] MOV ZREO,AX

10。 MOV AX,TABLE 是把符号地址TABLE里的内容送到AX里,指令执行完后,(AX)=1234H

LEA AX,TABLE 是把符号地址TABLE 的有效地址(这里是偏移量)送到指定寄存器AX里,指令执行完后,(AX)=0032H 11。执行完指令后,(AX)=1E00H 12。 LEA AX,CSTRING MOV DL,AX

MOV DH,[AX+6] 13。这个,,图,很麻烦了,所以就不画了~~大家可以看一下课本上P51--P53,很清楚,看完了这道韪也会了~~~ 14。LES BX,[2000]

MOV AX,ES:[BX]

注意:一开始我写的是: MOV AX,ES:[8000H],后来看到题目里要求写两条指令,所以

3 一条就不行了,就要画蛇添足~~~

15。 运算结果 : SF,ZF,CF,OF各位的值(从左至右依次往下~) (1)74D4H 0 0 0 0 (2) A5C1H 1 0 0 1 (3) 4240 H 0 0 1 0 (4) 0000 H 0 1 1 0 16。 接上表~

(1) 5D14 0 0 0 0 (2) A870 1 0 0 1 (3) D870 1 0 0 0

(4) 34E4 0 0 1 0 17。

(1).MOV AX,Z ;把Z送到AX SUB AX,X ;Z-X

ADD AX,W ;W+(Z-X)

MOV Z,AX ;结果保存在Z中 (2). MOV AX,R ;R送到AX中 ADD AX,9 ;R+9

MOV BX,X ;X送到BX中

ADD BX,6 ;X+6 ADD AX,BX ;(R+9)+(X+6),结果保存在AX中 MOV BX,W ; W送到BX中

SUB BX,AX ; W-(R+9)-(X+6),连续减去两个数,相当于减去这两个数的和~~

Page 3 of 41

MOV Z,BX ;最终结果送到Z中

(3)MOV AX,W ;把W送到AX

IMUL X ;W*X 注意:低十六位保存在AX里,高十六位保存在DX里 MOV BX,Y ;把Y送到BX 里 ADD BX,6 ;Y+6 IDIV BX ;(W*X)/(Y+6) 注意:商保存在AX里,余数保存在DX里 MOV Z,AX ;把商送到Z中, MOV R,DX ;把余数 送到R中 (4)MOV AX,W ;把W送到AX中 SUB AX,X ;W-X

CWD ;把AX中的十六位带符号数扩展成为32位,低十六位保存在AX中,高十六位保 ;在DX中 MOV BX,5 ;把5送到BX中 IDIV BX ;(W-X)/5 被除数为32位,除数为16位 商为16位 IMUL Y ;上一步结果再乖以Y,积为32位 MOV BX,2 ;把2送到BX中

IMUL BX ;上一步乘法所得的积再乘以2,各为64位 MOV Z,EAX ;把结果中低32位放入Z双字单元中 MOV [Z+4],EDX ;把结果中高32位放入Z+4双字单元中 18。指令 本条指令执行完后AX的内容执行完后CF,SF,ZF的值 MOV AX,1234H 1234H 0 0 0 MOV CL,4 1234H 0 0 0 ROL AX,CL 2341H 1 0 0 DEC AX 2340H 1 0 0 MOV CX,4 2340H 1 0 0 MUL CX 8918H 0 0 0

4

INT 20H

程序结束后,(AX)=8918H (DX)=0000H

19。指令执行完后AX的内容 执行完后CF ,SF,ZF和OF的值 MOV AX,0 0 0010 DEC AX FFFFH 0100 ADD AX,7FFFH 7FFEH 0000 ADD AX,2 8000H 0101 NOT AX 7FFFH 0101

SUB AX,0FFFFH 8000H 1101 ADD AX,8000H 0000H 1011

SUB AX,1 FFFFH 1101 AND AX,58D1H 58D1H 0000 SAL AX,1 B1A2H 0101 SAR AX,1 D8D1H 0100 NEG AX 272FH 1000 ROR AX,1 9397H 1001 20。(1)MOV AX,DATAX ADD DATAY,AX (2)MOV AX,DATAX ADD DATAY,AX MOV AX,[DATAX+2] ADD [DATAY+2] ,AX

Page 4 of 41

(3)本组指令的作用是:BX <------[DATAX]+[DATAY]+[1](CF的值) 带进位加法~ (4)MOV AX,DATAX MUL DATAY ;结果的高十六位保存在DX里,低十六位保存在AX里 (5)MOV AX,DATAX MOV DX,[DATAX+2] MUL DWORD DATAY ;结果的高三十二位保存在EDX里,低三十二位保存在EAX里

;这里所用的DWORD为一属性操作符,在第四章会学到~~ (6)MOV AX,DATAX DIV 17H ;结果商保存在AL中,余数在AH中 (7)MOV AX,DATAX CDW DIV DATAY 21。NEG DX NEG AX SBB DX,0

22。MOV AX,A ;把双字长数的低字放到AX中 MOV DX,[A+2] ;把双字长数的高字放到DX中 TEST DX,8000H ;测试双字长数的符号 JZ RIGHT ;如果是非负数,则直接保存 NEG DX ;如果是负数,则求补 NEG AX

SBB DX,0 RIGHT: MOV B ,AX MOV [B+2],DX

23。每条指令单独执行完后的结果依次为:

(1) 9AH (2)61H (3)0FBH (4)1CH (5)0 (6)0E3H 24。执行指令序列后,BX的内容为:0DAH 25。

(1)把53D乘以2的程序:

MOV AX,35H ;53D=35H SHL AX ,1

(2)把53除以2 的程序: MOV AX,35H SHR AX,1 其他的同理~~

26。这段程序完成的功能是:把DX:AX中的双字数据左移4位(相当于乘以16D)27。各条指令单独执行后,DX的值依次为:

(1) 5CH (2)17H (3)05C8H (4)72H (5)2017H (6)0CDH (7)0172H 05CCH

(9)0DCH

28。 该程序段执行完后,BX寄存器的内容是:C02DH

29。(1)从左到右把CONMAE中的字符串伟送到PRLINE的程序实现: LEA SI,CONAME ;把CONAME中第一个字节的偏移地址送到SI中

Page 5 of 41

5

8) (LEA DI,PRLINE ;把PRLINE中第一个字节 的偏移地址送到DI中 MOV CX,20 ;把重复次数放到CX里

CLD ;让SI DI从低地址指向高地址(即从左到右传送) REP MOVSB ;传送

(2)从右到左把CONMAE中的字符串传送到PRLINE中的程序实现: LEA SI ,CONAME LEA DI,PRLINE

MOV CX,20

STD ;和上面唯一不同的就是这次是从右到左,所以要从高地址批向低地址

REP MOVSB

(3)把CONAME中的第三和第四个字节装入AX的程序实现: LEA SI ,[CONAME+3] LODSW

(4)把AX寄存器的内容存入从PRLINE+5开始的字节中的程序实现: LEA DI ,[PRLINE+5]

STOSW

(5)检查CONAME字符串中有无空格字符,如有把它伟送给BH寄存器的程序实现:LEA DI,CONAME ;把CONAME中第一个字符偏移地址放入DI中 MOV CX,20 ;把重复次数放到CX中

MOV AL,20H ;把空格符的ASCII值放入AL中 CLD ;从低到高 REPNE SCASB ;比较

MOV BH,[DI-1]R ;把检查到的空格符送到BH中 30。

MOV CX,12H ;把重复次数放到CX中。这里用十六进制表示 MOV SI,0 ;初始化SI

MOV AX,26H ;把&字符的ASCII值放入AX CHECK: CMP AX,STRING[SI] ;依次查找

INC SI

LOOPNE CHECK ;找到了就退出

MOV AX,20H ;把空格符的ASCII值勤放入AX中 MOV STRING[SI-1],AX ;用空格符代替& 31。(1)用空格符清除PRINT_LINE域的程序实现: MOV AL,20H

LEA DI ,PRINT_LINE MOV CX,132

CLD

REP STOSB

(2)在STUDENT_ADDR中查找 第一个?_?的程序实现:

MOV AX,2DH ;把“—”的ASCII值放入AX MOV SI,0 ;初始化SI

MOV CX,9 ;把重复次数放入CX中 ;依次检查STUDENT-ADDR中的字符是否为\找到第一个停下来

Page 6 of 41

6

CHECK:CMP AX ,STUDENT_ADDR[SI] ;

INC SI

LOOPNZ CHECK

(3)在STUDENT_ADDR中查找最后一个”_“的程序实现:

;和第二题不同的就是这次是从右到左查询,所以SI的初始化为9 MOV AX,2DH MOV SI ,9

MOV CX,9

CHECK :CMP AX,STUDENT_ADDR[SI] DEC SI

LOOPNZ CHECK (4)程序实现:

MOV AL,2OH ;把空格符的ASCII值放入AL中

LEA DI ,STUDENT_NAME ;把STUDENT_NAME中第一个字符偏移地址放到DI中

MOV CX,30 ;把重复次数放到CX中

CLD ;让DI从低位移到高位

REPZ SCASB ;如果有不是空格符的,就退出

JZ STORE ;如果全是空格符,就转到STORE中 ;用*代替空格

STORE:MOV AL 2AH

MOV CX ,30

STD ;注意,这里是把前面从低到高移动的DI再从高到低移上去~~ REP STOSB (5)程序实现:

;把STUDENT_NAME 移到PRINT_LINE的前30个字节中 LEA SI, STUDENT_NAME LEA DI,PRINT_LINE MOV CX ,30 CLD

REP MOVSB

;把STUDENT_ADDR移到PRINT_LINE的后9个字节中 LEA SI ,[STUDENT_ADDR+9] LEA DI,[PRINT_LINE+132] MOV CX,9 STD

REP MOVSB 32。程序实现: 。。。 LEA SI,OLDS LEA DI,NEWS MOV CX,5 REPZ CMPSB JNZ NEW_LESS

Page 7 of 41

7

。。。

33。

(1)CMP DX,CX JA EXCEED (2)CMP BX,AX JG EXCEED (3)CMP CX,0 JZ ZERO

(4)CMP BX,AX JO OVERFLOW (5)CMP BX,AX JLE EQ_SMA (6) CMP DX,CX JBE EQ_CX 34。(1)跳转到:L1 (2)跳转到L1 (3)跳转到L2 (4)跳转到L5 (5)跳转到L5

35。

(1)可以引起转移到L1的指令有: NB ,BE ,NL ,LE (2)可以引起转移到L1的指令有: 同上

(3)可以引起转移到L1的指令有: B,BE ,L , LE

(4)可以引起转移到L1的指令有: NB ,NBE ,NL ,NLE (5)可以引起转移到L1的指令有: 同上 (6)可以引起转移 到L1的指令有: 同(3) (7)可以引起转移 到L1的指令有: 同上

36。

37。 程序流程图就不画了,呵呵,程序如下~~

MOV AL,STAUS[SI] ;把要测试的字节放到AL中

AND AL,2AH ;把第一,三,五位为一其他位为0的数--2AH,与这个字节比较,结果

;放到AL中

JZ ROUTINE_4 ;如果结果为0,则三位都为0 XOR AL,2AH ; 前面相与的结果再与2AH异或 JZ ROUTINE_1 ;如果结果为0,则三位都为1 BSF BL,AL ;

BSR BL ,AL CMP BL,CL

;如果向前和向后测试后,第一个1 的位置相同,说明只有一个1,则异或运算前有AL中有两个1

JE ROUTINE_2 ROUTINE_1

注:本题还有其他解法,请大家自己试试~~

8

Page 8 of 41

38。(1)当括号内是:LOOP时,循环四次,程序结束后 (AX)=05 (BX)= 16 (CX)=0 (DX)=0

(2) 当括号内是: LOOPE 时,不循环,程序结束后 (AX)=02 (BX)=04 (CX)=03 (DX)=02

(3)当括号内是:LOOPNE 时:循环三次,程序结束后

(AX)=04 (BX)=11 (CX)=01 (DX)=0

IBM-PC汇编语言程序设计(第二版)课后习题答案(清华大学出版社)(沈美明,温冬蝉著)第三章答案39--52

39。图,就不画了,呵呵~~自己看一下课本,P101~~ 40.。(1)0000 3100H (2)5100H (3)7100H

41。(1)目的地址:2004H 内容依次为: 56H F4H 23H 98H (2)目的地址: 384CH 内容依次为: 91H 34H F2H 01H

(3)目的地址: 寄存器,无物理地址~ 内容依次为:92H 6DH 42。 (1)PUSH AX (SP)<------(SP)-2

(SP+1)<-----(AH) (SP)<------(AL) (2)POP ESI

(ESI)<-------((ESP)+3,(ESP)+2,(ESP)+1, (ESP)) (ESP)<-------(ESP)+4 (3)PUSH [BX]

(SP)<------(SP)-2

(SP+1)<-----([BX+1]) (SP)<------([BX]) (4) PUSHAD

(ESP)<-------(EAX) (ESP-4)<-------(ECX) (ESP-8)<-------(EDX) (ESP-12)<-------(EBX)

(ESP-16)<-------(ESP) ;这里指的是指令执行前的ESP (ESP-20)<-------(EBP) (ESP-24)<-------(ESI) (ESP-28)<-------(EDI) (ESP)<-------(ESP)-32 (5)POP DS

(DS)<------((SP)+1,(SP)) (SP)<------(SP)+2 (6) PUSH 4

(SP)<-------(SP)-2 (SP+1)<-----0 (SP)<------4 43。(1) 2CE FF93H (2) 24B 76A0H (3)909 0804H (4) 6F 13ADH 44。(1)0FFFF FFFCH (2)0FFFF FFF8H (3)0000 0007H (4)0000 0099H 45。 (EAX)=0 (EBX)=25d 46。 (AX)=3d (DX)=7d 47。ADD ECX,EDX ADD ECX,ESI MOV EDI ,ECX

48。 IMUL BX,DX,100H执行的操作是: (BX)<-------(DX)*100H 49。程序实现:

Page 9 of 41

A2H 4CH 9

MOV AL,BL CBW IDIV CL IMUL 2

MOV DX,AX

50。

JMP DI 是直接跳转,执行的操作是: (IP)<-----(IP)+(DI)

JMP [DI]是间接跳转,执行的操作是: (IP)<----(IP)+([DI])跳转到DI中所指向的内存单元中的指令地址~

51。假设数组名为NUMBERS,程序如下~ MOV BX,0 ;后面用到~

MOV CX,100H ;把循环次数放入CX MOV AL,42H

MOV SI,0 ;初始化SI ;CHECK 用来实现查找功能~

CHECK : CMP AL ,NUMBERS[SI]

INC SI

JB STORE1 ;大于42H的数的个数存入UP

JA STORE2 ;小于42H的的数的个数存入DOWN中~ LOOP CHECK ;相等继续循环~

STORE1 INC BL ;找到一个大于42 的数,BL值增加1~ MOV UP,BL LOOP CHECK STORE2 INC BH

MOV DOWN ,BH

LOOP CHECK

52。图,也不用画了~~呵呵~好了,本章结束

10

第四章

1。指令下列指令的错误

(1) MOV AH,BX 源操作数与目的操作数长度不相同~

(2) MOV [BX],[SI] 这是两个内存单元在传递数据,而这在汇编语言中是不允许的~~~ (3) MOV AX,[SI][DI] 不能用两个变址连用,其中一个应为基址~ (4) MOV MYDAT[BX][SI],ES:AX 同(2) (5) MOV BYTE PTR[BX],1000 必须有一个为寄存器 (6)MOV BX,OFFSET MYDAT[SI] OFFSET 不能与复杂操作数相连~ (7)MOV CS,AX 不能对CS赋值~

(8)MOV ECX,AX 操作数类型不同~ 2。(1)合法 (2)非法 (3)非法 (4)非法 3。(1)非法,操作数类型不同 (2)合法

(3)非法,不允许两个内存单元直接传递数据,你把人家CPU放哪了?~~~呵~ (4)合法~ (5)合法~

Page 10 of 41

(6)合法

(7) 非法~,必须有一个寄存器~~把CPU放哪了?~~ (8)非法,两个内存单元地址相加没有意义~ (9)合法

(10)非法,同(3) 4。(1)两内存单元传递数据 (2)操作数类型不同

(3)跳转指令只能跳转到符号地址

(4)转移指令后不能为变量,只能为标号 (5)格式不对, 应为 NEAR PTR 。。。 5。图,就不画了~~ 6。(1)DW 5150H

(2)MOV AX,5150H

MOV ADDRESS ,AX

等,写出几个就可以~~ 7。DATASG SEGMENT

FLD1B DB 'personal computer' FLD2B DB 10 DUP (32) FLD3B DB 20H

FLD4B DB 01011001B FLD5B DB '32654' FLD6B DB 10 DUP (0)

FLD7B DB 'PART1',DUP 20 (?),'PART2',DUP 50 (?),'PART3',DUP 14 (?) FLD1W DW 0FFF0H FLD2W DW 01011001B FLD3W DW FLD7B

FLD4W DW 5,6,7,8,9 FLD5W DW 5 DUP (0)

FLD6W DW (FLD6W-FLD1W)-(FLD7B-FLD1B) 8。PLENTH 的值为22,GE表示该数据段的长度~ 9。L的值为7

10。(1)MOV AX,OFFSET LNAME

(2)MOV SI,WORD PTR CODE_LIST (3)CODE_LENGHT EQU $-CODE_LIST 11。代码如下: DATA_SEG SEGMENT DB 5 DATA_LIST DW 0FFFFH,0,2,5,4, 5 DUP (?) DATA_SEG ENDS

CODE_SEG SEGMENT

ASSUME CS:CODE_SEG,DS:DATA_SEG MOV AX,5 MOV MAX,AX MOV AX,0FFFFH MOV MIN,AX

CODE_SEG ENDS 12。(1)10025 (2)19 (3)2548 (4)3

Page 11 of 41

11

(5)103 (6)0FFFFH (7)1 (8)3

13。分别汇编成为: MOV AX,0AH MOV BL,0AH MOV CL,1

14。(1)(AX)=1 (2)(AX)=2 (3)(CX)=14H (4)(DX)=32H (5)(CX)=1] 15。(1)操作符错误 改为: DATA_SEG SEGMENT (2)缺少段名 在前面加个段名

(3)引用应该从;开始 把那个“/”改成“;” (4)结构混乱 改为: MAIN_PROC PROC FAR 。。。。 MAIN_PROC ENDP END

16。程序框架如下:

DATA_SEG SEGMENT ;定义数据段

ORG 0E000H ;让下一字节地址为0E000H FIRST_TYPE EQU THIS WORD ;建立一个与下一存储单元有相同段地址和偏移地址的操作数 DATA_GROUP DB 100 DUP(?) ;给DATA_GROUP 分配100个字节的空间 DATA_SEG ENDS ;数据段结束 STACK_SEG SEGMENT ;定义堆栈段

ALIGN 16 ;让下一字节从小段首地址开始 STACK DB 100 DUP (?) ;为堆栈分配空间 STACK_SEG ENDS ;

CODE_SEG SEGMENT

ASSUME CS:CODE_SEG ,DS:DATA_SEG ,SS:STACK_SEG

ORG 1000H ;让下条指令的第一个字节从1000H开始 START : MOV AX,DATA_SEG MOV DS,AX MOV AX,STACK_SEG MOV SS,AX

.......

CODE_SEG ENDS

END START ;结束~ 17。程序如下:

D_SEG SEGMENT ;数据段定义 AUGEND DD 99251 D_SEG ENDS

E_SEG SEGMENT ;附加段定义 ADDEND DD -15926

Page 12 of 41

12

E_SEG ENDS

C_SEG SEGMENT ;代码段定义 ASSUME CS:C_SEG , DS:D_SEG,ES:E_SEG START: MOV AX,D_SEG MOV DS,AX MOV AX,E_SEG MOV ES,AX

MOV EAX,DS:AUGEND ADD EAX,ES:ADDEND MOV DS:SUM,EAX

C_SEG ENDS

END START ;结束 18。

19。需要加上PTR伪操作的有: (2)(3)(4)

第五章

5.1 试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来 .model small .stack 100H .code main proc far Start: push dx mov ax,0 push ax

mov ah,01H int 21H

cmp al,61H

jl lop1

cmp al,7BH jge lop1

sub al,20H mov dl,al

lop1:mov ah,2 int 21H ret

End start

Page 13 of 41

13

5.2 编写一个程序,从键盘接受一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符. .model small .386 .code

MAIN PROC FAR start: push ds sub ax,ax push ax

input: mov ah,7H int 21H cmpe:

cmp al,20H JE exit

cmp al,61H JL input

cmp al,7AH JG input print: sub al,01H mov dl,al mov ah,02H int 21H

add al,01H mov dl,al mov ah,02H int 21H

add al,01H mov dl,al mov ah,02H int 21H

;输出换行回车 mov dl,0AH mov ah,02H int 21H

Page 14 of 41

14

jmp input

exit : ret

MAIN ENDP END start

5.3 将AX寄存器中的16位数分成4组,每组4位,然后把这四组数分别放在AL、BL、CL、DL中。 .model small .data x DB 4 dup(?) .stack 100H .code

MAIN PROC FAR start: push ds and ax,00H push ax

mov ax,1234H

mov cx,04H mov si,00H lop: push cx

mov cl,04H rol ax,cl push ax

and al,0FH

mov BYTE PTR x[si],al pop ax pop cx add si,2 Loop lop mov al,[X] mov bl,[X+2] mov cl,[X+4] mov dl,[X+6] print:

mov ah,02H int 21H

mov dl,al mov ah,02H int 21H

Page 15 of 41

15

mov dl,bl mov ah,02H int 21H mov dl,cl mov ah,02H int 21H exit: ret

MAIN ENDP

END start

5.4 编写一个程序,要求比较两个字符串STRING1和STRING2所含字符是否相同,若相同则显示\TCH\,若不同在显示:\TCH\。 .model small

.data

STRING1 DB 'I must study hard' STRING2 DB 'I must study hard' X DB 'MATCH .$' Y DB 'NO MATCH.$' .stack 100H .code main proc far Start: push dx mov ax,0 push ax

mov ax,@data mov ds,ax mov es,ax

lea si,STRING1 lea di,STRING2 cld

mov cx,(string2-string1)/ type STRING2 ret

End start

5.5编写一个程序,要求能从键盘接收一个个位数N,然后响铃N次,(响铃的ASCII为07)。 这题比较有意思,呵呵。 model small .code

main proc far start:

Page 16 of 41

16

push ds

sub ax,ax push ax input:

mov ah,01H int 21H cmp al,20H je exit cmp al,30H jle input cmp al,3AH jge input sub al,30H mov cx,ax and cx,0FFH lop:

mov dl,07H mov ah,2H int 21H loop lop jmp input

exit :

17

ret main endp end start

5.6编写程序,将一个包含有20个数据的数组M分成两个数组:正数数组和负数数组N,并分别把这两个数组中的数据个数显示出来。 .model small .386 .data

M DB 1,2,3,4,5,6,7,8,9,10,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10 P DB 20 dup(?) N DB 20 dup(?) .code

MAIN PROC FAR start: PUSH ds AND ax,0 PUSH ax

MOV ax,@data mov ds,ax MOV bx,0 MOV si,0

Page 17 of 41

MOV di,0 MOV cx,20D

cmpe :

CMP M[bx],0 JL ifLow hight :

MOV al,byte ptr M[bx] MOV byte ptr P[si],al inc si

JMP commonContrl ifLow :

MOV al,byte ptr M[bx] MOV byte ptr N[di],al INC di

commonContrl: INC bx loop cmpe mov ax,si call showNumber call printCR

mov ax,di

call showNumber exit: ret

MAIN ENDP

;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;; showNumber PROC NEAR covernum: DAA

MOV dx,ax MOV cl,2H show: ROL dl,4H push dx AND dl,0fH ADD dl,30H MOV ah,02H int 21H pop dx loop show ret

showNumber ENDP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; printCR PROC NEAR

Page 18 of 41

18

mov dl,0aH mov ah,02H int 21H mov dl,0dH mov ah,02H int 21H ret

printCR ENDP end start

5.7编制一个汇编语言程序,求出首地址为DATA的100D字数组中的最小偶数,并把它放在AX中。

此题根据题意要求应该使用完整汇编格式,因为精简格式也使用DATA.... dataare segment DATA DW 3322H,4555H,200H,3544H,1245H num DB ($-DATA)/2 dataare ends

code segment

assume cs:code,ds:dataare MAIN PROC FAR start: push ds mov ax,0H push ax

mov ax,dataare

mov ds,ax

mov dx,0H ;偶数数量计数 mov cx,Word ptr [num] mov si,0H isO:

mov bx,WORD PTR DATA[si] shr bx,1H

jnc addDX

jmp commonControl addDX:

ADD dx,1H cmp dx,1H je firstAXValue compare:

mov bx,WORD PTR DATA[si] cmp bx,ax jge commonControl mov ax,bx commonControl:

Page 19 of 41

19

ADD si,2H

loop isO jmp exit firstAXvalue:

mov ax,WORD PTR DATA[si] jmp compare exit: ret

MAIN ENDP code ends END start 5.8没有做。。

5.9编写一个汇编语言程序,要求从键盘上接收一个思维的十六位进制数,并在终端上显示与它等值的二进制数。 .model small .386 .code

main proc far start: push ds mov ax,0 push ax mov ax,0 mov cx,4 mov dx,0 input:

mov ah,1H int 21H cmp al,30H jl input cmp al,39H jle s cmp al,61H jl input cmp al,66H jg input sub al,27H s:

sub al,30H add dl,al cmp cx,1H je f rol dx,4

Page 20 of 41

20

f: loop input exit:

call print ret main endp print proc near mov cx,10H p:

rol dx,1 push dx and dx,1 add dx,30H mov ah,2 int 21H pop dx loop p ret

print endp end start

5.10设有一段英文,其变量字符名为ENG,并以$字符结束。试编写一程序,查对单词SUN

21 在该文中的出现次数,并以格式\显示出次数。 .model small

.386

.data

ENG db 'SUN's SUN JAVA',24H ;;;;24H = $ MESSAGE db 'SUN:','$' .stack 100H .code

MAIN PROC FAR start: PUSH DS AND AX,0 PUSH AX

MOV AX,@data MOV DS,AX

;------------------------ MOV AX,0H MOV SI,1H subSI1:

SUB SI,1H subSI2:

Page 21 of 41

SUB SI,1H compareS: ADD SI,1H

MOV DL,ENG[SI] CMP DL,24H JE print CMP DL,53H JNE compareS compareU: ADD SI,1H MOV DL,ENG[SI] CMP DL,55H JNE subSI2 compareN:

ADD SI,1H

MOV DL,ENG[SI] CMP DL,4EH JNE subSI1 INC AX JMP compares print:

LEA DX,MESSAGE PUSH AX

MOV AH,09H INT 21H POP AX

call showNumber

exit: ret

MAIN ENDP

;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;; showNumber PROC NEAR covernum: DAA MOV dx,ax MOV cl,4H show: ROL dx,4H push dx AND dx,0fH ADD dx,30H MOV ah,02H int 21H pop dx

Page 22 of 41

22

loop show

ret

showNumber ENDP END start

5.11从键盘输入一系列以$为结束副的字符串,然后对其中的非数字字符计数,并显示出计数结果。 .model small .386 .code

MAIN PROC FAR start: push ds mov ax,0 push ax

mov cx,0 input:

mov ah,1H int 21H compare: cmp al,24H je print cmp al,30H jl addCount cmp al,39H jg addCount addCount: add ax,1H jmp input print:

call showNumber exit: ret

MAIN ENDP

;;;;;;;;;;;;;;;;;注意,ShowNumber这个子过程有问题,请自行修改;;;;;;;;;;;;;;;; showNumber PROC NEAR covernum: DAA MOV dx,ax MOV cl,2H show: ROL dl,4H push dx

AND dl,0fH ADD dl,30H

Page 23 of 41

23

MOV ah,02H int 21H pop dx loop show ret

showNumber ENDP

END start

5.12 有一个首地址为MEM的100D字数组,试编制程序删除数组中所有为零的项,并将后续项向前压缩,最后将数组的剩余部分补上零。 .model small .386

.stack 100H .data mem

dw

12,0,0,0,0,0,1,2,3,6,4,7,8,2,1,0,0,54,5,0,2,4,7,8,0,5,6,2,1,4,8,5,1,45,7,5,1,2,0,2,4,0,2,54,0,12,0,0,0,0,0,1,2,3,6,4,7,8,2,1,0,0,54,5,0,2,4,7,8,0,5,6,2,1,4,8,5,1,45,7,5,1,2,0,2,4,0,2,54,0,45,7,5,1,2,0,2,4,0,2 .code

MAIN PROC FAR start: push ds and ax,0 push ax

mov ax,@data mov ds,ax

;---------------------- mov ax,0H mov bx,64H mov cx,64H mov si,0FFFEH repeat:

ADD si,2H

cmp MEM[si],0H JE calls loop repeat calls: INC ax call sort cmp ax,1H JE lastValue DEC cx jmp repeat exit :

Page 24 of 41

24

ret

lastValue:

mov mem[bx],0H DEC cx jmp repeat

MAIN ENDP sort PROC NEAR push cx push si sub si,2H s:

add si,2H

mov dx,mem[si] mov mem[si+2],dx loop s return: pop si pop cx ret sort ENDP END start

第六章

2、答:

(1) NAME1 NAMELIST < > (2) MOV AX,DATA ;假设结构变量NAME1定义在数据段DATA中MOV DS,AX MOV ES,AX ;

MOV AH,10

LEA DX,NAME1 INT 21H ;

MOV CL,NAME1.ACTLEN MOV CH,0

LEA SI,NAME1.NAMEIN LEA DI,DISPFILE CLD REP MOVSB

6、答: SKIPLINES PROC NEAR PUSH CX PUSH DX

Page 25 of 41

25

MOV CX,AX NEXT: MOV AH,2 MOV DL,0AH INT 21H MOV AH,2 MOV DL,0DH INT 21H LOOP NEXT POP DX POP CX

RET

SKIPLINES ENDP

7、答:

dseg segment

num dw 76,69,84,90,73,88,99,63,100,80 n dw 10 s6 dw 0 s7 dw 0 s8 dw 0 s9 dw 0 s10 dw 0 dseg ends

code segment

main proc far

assume cs:code, ds:dseg start: push ds sub ax, ax push ax

mov ax, dseg mov ds, ax

call sub1 ret main endp

sub1 proc near push ax push bx push cx push si

Page 26 of 41

26

mov si, 0 mov cx, n next:

mov ax, num[si] mov bx, 10 div bl mov bl, al cbw

sub bx, 6 sal bx, 1 inc s6[bx] add si,2 loop next pop si pop cx pop bx pop ax ret

sub1 endp

code ends end start

8、答: data segment maxlen db 40

n db ?

table db 40 dup (?)

char db 'a' ; 查找字符?a? even

addr dw 3 dup (?) data ends code segment

assume cs:code, ds:data main proc far start: push ds mov ax, 0 push ax

mov ax, data mov ds, ax

Page 27 of 41

27

lea dx, maxlen

mov ah, 0ah

int 21h ; 从键盘接收字符串

mov addr, offset table mov addr+2, offset n

mov addr+4, offset char

mov bx, offset addr ; 通过地址表传送变量地址

call count ; 计算CHAR的出现次数 call display ; 显示

ret

main endp

count proc near ; count子程序 push si push di push ax push cx

mov di, [bx] mov si, [bx+2] mov cl, byte ptr[si] mov ch, 0

mov si, [bx+4] mov al, byte ptr[si] mov bx, 0 again:

cmp al, byte ptr[di] jne l1 inc bx l1: inc di loop again pop cx pop ax pop di pop si ret

count endp

display proc near ; display子程序

Page 28 of 41

28

call crlf ; 显示回车和换行 mov dl, char mov ah, 2 int 21h

mov dl, 20h mov ah, 2 int 21h

mov al, bl and al, 0fh add al, 30h cmp al, 3ah jl print add al, 7 print: mov dl, al int 21h call crlf ret

display endp

crlf proc near ; crlf子程序 mov dl, 0dh mov ah, 2 int 21h mov dl, 0ah mov ah, 2 int 21h ret

crlf endp code ends end start

第七章

1、 答: CLRB MACRO N, ARRAY CLD

MOV CX, N MOV AL, 20H LEA DI, ARRAY REP STOSB ENDM

Page 29 of 41

29

2、答:

WAGES MACRO RATE,HOUR MOV AL,RATE MOV BL,HOUR

MUL BL ;计算周工资 ;

ADD AX,AX

ADD AX,AX ;一个月有4周

MOV WAG,AX ;暂存中间结果

ADD BL,BL

ADD BL,BL ;计算月出工小时数

MOV AL,BL MOV AH,0 MOV BL,10 DIV BL

MOV BL,3

MUL BL ;计算奖金

ADD WAG,AX ;计算工资总数 ENDM 宏展开:

1 MOV AL,R1 1 MOV BL,42 1 MUL BL

1 ADD AX,AX 1 ADD AX,AX 1 MOV WAG,AX 1 ADD BL,BL 1 ADD BL,BL 1 MOV AL,BL 1 MOV AH,0 1 MOV BL,10 1 DIV BL

1 MOV BL,3 1 MUL BL

1 ADD WAG,AX

3、答:

(1) 调用有效 1 PUSH AX 2 MOV AX, P1 2 SUB AX, P2

Page 30 of 41

30

1 CMP AX, 0

1 JGE ??0000 1 NEG AX

1 ??0000: MOV DISTANCE, AX 1 POP AX

(2) 调用有效 1 PUSH AX 2 MOV AX, [BX] 2 SUB AX, [SI] 1 CMP AX, 0 1 JGE ??0001

1 NEG AX

1 ??0001: MOV X[DI], AX 1 POP AX

(3) 调用无效,有错误指令 1 ??0002: MOV 240H, AX (4) 调用有效,但无意义 宏展开略。

4、答:

SEND MACRO SCHARS, DCHARS LOCAL NEXT, EXIT PUSH AX PUSH SI MOV SI, 0

NEXT: MOV AL, SCHARS[SI] MOV DCHARS[SI], AL CMP AL, 24H JZ EXIT INC SI JMP NEXT EXIT: POP SI POP AX ENDM

5、答:

BIN_SUB MACRO OPERAND,COUNT,RESULT LOCAL NEXT

LEA BX,OPERAND MOV CX,COUNT DEC CX

MOV AL,[BX] NEXT: INC BX

Page 31 of 41

31

SUB AL,[BX] LOOP NEXT

MOV RESULT,AL ENDM

7、答: 宏展开: 2 DATA0 DW ? 2 DATA1 DW ?

9、答:

1 MOV TAB , 0 1 MOV TAB+1, 1 1 MOV TAB+2, 2 1 MOV TAB+3, 3 1 MOV TAB+4, 4 1 MOV TAB+5, 5 1 MOV TAB+6, 6

10、答:

STORE MACRO X IRPC X, 0123456 MOV TAB+&X, X ENDM ENDM

12、答:

FINSUM MACRO X,Y,SUM MOV AX, X MOV BX, Y .IF AX > BX ADD BX, BX ADD AX, BX MOV SUM, AX .ELSE

ADD AX, AX ADD AX, BX MOV SUM, AX .ENDIF ENDM

Page 32 of 41

32

14、答:

DOS21 MACRO DOSFUNC,BUFF IFNB áBUFF?

MOV AH,DOSFUNC MOV DX,OFFSET BUFF INT 21H ELSE

MOV AH,DOSFUNC INT 21H ENDIF ENDM

展开宏调用: 1 MOV AH,01 1 INT 21H

1 MOV AH,0AH

1 MOV DX,OFFSET IPFIELD 1 INT 21H

第八章

1、 答:

(1)00048H (2)00020H

2、答: mov ah, 02 mov dl, ?T? mov bx, 0 mov ds,bx mov bx, 21h * 4 call far ptr [bx]

3、答: mov al, 12h out 25h, al

4、答: mov dx, 1000h in ax, dx

8、答: (SP) = 00FA (SS) = 0300 (IP) = 0040

(FLAGS) = 0040

Page 33 of 41

33

9、答:

14H*4 = 50H ,∴ (00050H)= 偏移地址,(00052H)= 段地址

10、答: push ds

mov ax, seg int_rout mov ds, ax

mov dx, offset int_rout mov al, 09 mov ah, 25h int 21h pop ds

12、

答:D3→D2→D3→D4→D5→D1→D3→D5

13、

答:D3→D2→D4→D5→D1→D3→D5

第九章

1、 答:

二者不同点是功能1输入字符可回显,功能8输入字符不回显。

2、答: dseg segment

scode db 7,5,9,1,3,6,8,0,2,4 buffer db 10 dup (?)

dseg ends

;-------------------------------------------------------------------- cseg segment main proc far mov ax,dseg mov ds,ax mov si,0

mov cx,10 lea bx,scode

input: mov ah,01 ; 键盘输入 int 21h

and al,0fh ; ASCII→数字 xlat ; 换码

mov buffer[si],al ; 存入缓冲区 inc si ; 修改地址指针

loop input ; 输入下一个数字 mov ax,4c00h ; 返回DOS

Page 34 of 41

34

int 21h

main endp cseg ends end main

3、答: ((24行×80)+40列)×2 = 3920 = 0F50H

4、答:

mov dh, 0ch ; 第12行 mov dl, 08h ; 第8列 mov bh, 0 ; 0页 mov ah, 2 ; 置光标 int 10h ; BIOS调用

5、答:

mov ah, 7 ; 屏幕初始化 mov al, 0 ; 全屏为空格 mov bh, 07h ; 正常属性 mov ch,12 ; 左上行 mov cl, 0 ; 左上列 mov dh, 22 ; 右下行 mov dl, 39 ; 右下列 int 10h ; BIOS调用

6、答:

(1) mov ah, 3 ;读光标位置 mov bh, 0 ;页号 int 10h ;BIOS调用

(2) mov dh, 18h ;第25 行 mov dl, 0 ;第0 列 mov bh, 0 ;0页 mov ah, 2 ;置光标位置 int 10h ;BIOS调用 (3) mov ah, 2 ;置光标位置 mov bh, 0 ;0页 mov dx, 0 ;0行0 列 int 10h ; BIOS调用

mov ah, 9 ;显示字符及属性 mov al, ?M? ;字符 mov bh, 0 ;0页 mov bl, 7 ;正常属性 mov cx, 1 ;显示次数 int 10h ;BIOS调用

Page 35 of 41

35

7、答:

message db ?Try again, you have? Count db ?n? db ? starfighters left.$? ; … …

add cl,30h ;二进制数→ASCII mov count, cl ;存入COUNT lea dx, message ;字符串地址 mov ah, 09 ;显示字符串 int 21h ;DOS调用

9、答:

mess db ?What is the date(mm / dd / yy)?, 07, ?$? date db 10,0,10 dup (? ?) …

mov ah, 09 ;显示字符串 lea dx, mess ;字符串地址 int 21h

mov ah, 0ah ;键盘输入 lea dx, date ;缓冲区地址 int 21h

11、答:

MODE COM2:12, N, 8, 1

第十章

1。答:

(1)EXYRN SUBPRO:FAR (2)PUBLIC SUBPRO

2、答:

(1)PUBLIC QTY, VALUE, PRICE

(2)EXTRN QTY:BYTE, VALUE:WORD, PRICE:WORD

3、答: 模块1:

PUBLIC VAR1, VAR2, LAB3 模块2:

PUBLIC VAR3, LAB2

EXTRN VAR1:DWORD, VAR2:BYTE, LAB1:NEAR, LAB3:FAR 模块3:

PUBLIC LAB3

EXTRN VAR1:DWORD, VAR2:BYTE, LAB1:NEAR, LAB2:FAR

Page 36 of 41

36

4、答:

EXTRN SUBMUL:FAR SSEG SEGMENT DW 64 DUP(?) SSEG ENDS

;-------------------------------------------- DSEG SEGMENT QTY DW ? PRICE DW ? DSEG ENDS

;--------------------------------------------- CSEG1 SEGMENT

ASSUME CS:CSEG1, DS:DSEG, SS:SSEG CALLMUL PROC FAR MOV AX, DSEG MOV DS,AX

MOV AX, PRICE MOV BX, QTY

CALL FAR PTR SUBMUL …

CALLMUL ENDP

CSEG1 ENDS END CALLMUL

;------------------------------------------------ PUBLIC SUBMUL CSEG2 SEGMENT ASSUME CS:CSEG2 SUBMUL PROC FAR MUL BX RET

SUBMUL ENDP CSEG2 ENDS

END

;--------------------------------------------------

5、答:

1 D_SEG SEGMENT 2 X DW 16 DUP(?) 3 Y DW 16 DUP(?) 4 D_SEG ENDS

Page 37 of 41

37

;-------------------------------------------- 5 E_SEG SEGMENT 6 R DW 16 DUP(?) 7 E_SEG ENDS

;--------------------------------------------- 8 C_SEG SEGMENT

9 ASSUME CS:C_SEG, DS:D_SEG, ES:E_SEG 10 MAIN PROC FAR 11 MOV AX, D_SEG 12 MOV DS,AX 13 MOV AX, E_SEG 14 MOV ES, AX 15 CALL COMPUTE 16 …

17 MAIN ENDP

;------------------------------------------------ 18 COMPUTE PROC NEAR 19 MOV CX,16 20 MOV SI,0 21 MOV DI,0 22 MOV BX,0

23 NEXT: MOV AX, X[SI] 24 ADD AX, Y[DI] 25 SUB AX, 3

26 MOV ES:R[BX],AX 27 INC SI 28 INC DI 29 INC BX

30 LOOP NEXT 31 RET

32 COMPUTE ENDP 33 C_SEG ENDS

;--------------------------------------------------- 34 END MAIN

(1) D_SEG SEGMENT …

D_SEG ENDS

;---------------------------------------- E_SEG SEGMENT …

E_SEG ENDS

;--------------------------------------- C_SEG1 SEGMENT

Page 38 of 41

38

ASSUME CS:C_SEG, DS:D_SEG, ES:E_SEG MAIN PROC FAR MOV AX, D_SEG MOV DS,AX MOV AX, E_SEG MOV ES, AX

CALL FAR PTR COMPUTE …

MAIN ENDP C_SEG1 ENDS

;------------------------------------------------ C_SEG2 SEGMENT

ASSUME CS:C_SEG2, DS:D_SEG, ES:E_SEG COMPUTE PROC FAR …

COMPUTE ENDP

C_SEG2 ENDS

;-------------------------------------------------- END MAIN

(2) D_SEG SEGMENT

D_SEG ENDS

;---------------------------------------- E_SEG SEGMENT …

E_SEG ENDS

;--------------------------------------- EXTRN COMPUTE:FAR PUBLIC X, Y, R

C_SEG1 SEGMENT

ASSUME CS:C_SEG, DS:D_SEG, ES:E_SEG MAIN PROC FAR MOV AX, D_SEG MOV DS,AX MOV AX, E_SEG MOV ES, AX

CALL FAR PTR COMPUTE …

MAIN ENDP C_SEG1 ENDS

END MAIN

;-------------------------------------------------- EXTRN X:WORD, Y:WORD, R:WORD

Page 39 of 41

39

PUBLIC COMPUTE

C_SEG2 SEGMENT

ASSUME CS:C_SEG2, DS:D_SEG, ES:E_SEG COMPUTE PROC FAR MOV AX, D_SEG MOV DS,AX MOV AX, E_SEG MOV ES, AX …

COMPUTE ENDP C_SEG2 ENDS END

;--------------------------------------------------

6、答: .model small .stack 100h .data public data1 dw 1228 data2 dw 52400 result dd ? quotient dw ? remainder dw ? .code

extrn dmul:far,ddiv:far start: mov ax,@data mov ds,ax mov dx, data1 mov ax, data2 push ax push dx

call far ptr dmul call far ptr ddiv mov ah,4ch int 21h

end start

;---------------------------------------------- .model small extrn result:dword .code

public dmul dmul proc far_ _

Page 40 of 41

40

push bp mov bp,sp mov ax,[bp+6] mov bx,[bp+8] mul bx

mov word ptr result,ax mov word ptr result+2,dx pop bp ret dmul endp

end

;--------------------------------------------------- .model small

extrn quotient:word, remainder:word .code

public ddiv ddiv proc far_ _ push bp mov bp,sp mov bx,[bp+6] mov ax,[bp+8] mov dx,0 div bx

mov quotient,ax mov remainder,dx pop bp ret dmul endp end

Page 41 of 41

41

《汇编语言程序设计》习题答案(第二版,沈美明,温冬婵,清华大学出版社)

汇编语言程序设计(第二版)第二章1、答:直接由指令指定的I/O端口数为256个。2、答:3、答:字节单元:(30022H)=ABH,(30024H)=EFH字单元:(30021H)=AB34H,(30022H)=CDABH。4、答:3017:000
推荐度:
点击下载文档文档为doc格式
4m61b3v4f03ibqw7sinb
领取福利

微信扫码领取福利

微信扫码分享