汇编语言课后习题答案

更新时间:2023-11-10 23:40:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

2.1已知DS=2000H、BX=0100H、SI=0002H,存储单元[20100H]~[20103H]依次存放12 34 56 78H,[21200H]~[21203H]依次存放2A 4C B7 65H,说明下列每条指令执行完后AX寄存器的内容。

(1) mov ax,1200h (2) mov ax,bx (3) mov ax,[1200h] (4) mov ax,[bx] (5) mov ax,[bx+1100h] (6) mov ax,[bx+si] (7) mov ax,[bx][si+1100h] 〔解答〕 (1)AX=1200H (2)AX=0100H

(3)AX=4C2AH ;偏移地址=bx=0100h (4)AX=3412H ;偏移地址=bx=0100h (5)AX=4C2AH ;偏移地址=bx+1100h=1200h

(6)AX=7856H ;偏移地址=bx+si=0100h+0002h=0102h

(7)AX=65B7H ;偏移地址=bx+si+1100h=0100h+0002h+1100h=1202h

〔习题2.2〕指出下列指令的错误 (1) mov cx,dl (2) mov ip,ax (3) mov es,1234h (4) mov es,ds (5) mov al,300 (6) mov [sp],ax (7) mov ax,bx+di

(8) mov 20h,ah 〔解答〕

(1)两操作数类型不匹配 (2)IP指令指针禁止用户访问 (3)立即数不允许传给段寄存器 (4)段寄存器之间不允许传送 (5)两操作数类型不匹配 (6)目的操作数应为[ SI ] (7)源操作数应为 [BX+DI] (8)立即数不能作目的操作数

〔习题2.5〕已知SS = 2200H、SP = 00B0H,画图说明执行下面指令序列时,堆栈区和SP的内容如何变化? mov ax,8057h

push ax mov ax,0f79h push ax pop bx pop [bx] 〔解答〕

mov ax,8057h push ax mov ax,0f79h push ax

pop bx ;bx=0f79h pop [bx] ;DS:[0f79h]=8057h

〔习题2.6〕给出下列各条指令执行后AL值,以及CF、ZF、SF、OF和PF的状态: mov al,89h add al,al add al,9dh cmp al,0bch sub al,al dec al inc al 〔解答〕

mov al,89h ; AL=89h CF ZF SF OF PF add al,al ; AL=12h 1 0 0 1 1 ; 1000 1001 +1000 1001 10001 0010

add al,9dh ; AL=0afh 0 0 1 0 1 ; 0001 0010 + 1001 1101

1010 1111

cmp al,0bch ; AL=0afh 1 0 1 0 1 ; 1010 1111 -1011 1100 * 0100 0011

sub al,al ; AL=00h 0 1 0 0 1

dec al ; AL=0ffh 0 0 1 0 1 ; 0000 0000 - 0000 0001 *1111 1111

inc al ; AL=00h 0 1 0 0 1 ;1111 1111 +0000 0001 *1111 1111

必考:〔习题2.10〕指出下列指令的错误:(1) xchg [si],30h

(2) pop cs (3) sub [si],[di] (4) push ah (5) adc ax,ds (6) add [si],80h (7) in al,3fch (8) out dx,ah

〔解答〕

(1)xchg的操作数不能是立即数 (2)不应对CS直接赋值

(3)两个操作数不能都是存储单元 (4)堆栈的操作数不能是字节量 (5)adc的操作数不能是段寄存器 (6)没有确定是字节还是字操作 (7)in不支持超过FFH的直接寻址 (8)out只能以AL/AX为源操作数

〔习题2.11〕给出下列各条指令执行后的结果,以及状态标志CF、OF、SF、ZF、PF的状态。 mov ax,1470h

and ax,ax or ax,ax xor ax,ax not ax test ax,0f0f0h

〔解答〕

mov ax,1470h ;AX=1470H CF ZF SF OF PF

and ax,ax ;AX=1470H 0 0 0 0 0 ;0001 0100 0111 0000

or ax,ax ;AX=1470H 0 0 0 0 0 xor ax,ax ;AX=0000H 0 1 0 0 1 not ax ;AX=FFFFH 0 1 0 0 1 test ax,0f0f0h ;AX=FFFFH 0 0 1 0 1

注意:MOV和NOT指令不影响标志位;其他逻辑指令使CF=OF=0,根据结果影响其他标志位。

〔习题2.26〕按照下列要求,编写相应的程序段:(1)起始地址为string的主存单元中存放有一个字符串(长度大于6),把该字符串中的第1个和第6个字符(字节量)传送给DX寄存器。

mov si,0

mov dl,string[si] ;第1个字符送dl寄存器 mov si,5

mov dh,string[si] ;第6个字符送dh寄存器

(2)从主存buffer开始的4个字节中保存了4个非压缩BCD码,现按低(高)地址对低(高)位的原则,将它们合并到DX中。

xor si,si ;si清零

mov al,buffer[si] ;第一字节 inc si

mov ah,buffer[si] ;第二字节 mov cl,4

shl ah,cl ;BCD码移到高半字节 or al,ah ;组合成压缩BCD码 mov dl,al ;存入dl寄.. inc si

mov al,buffer[si] ;第三字节 inc si

mov ah,buffer[si] ;第四字节 mov cl,4

shl ah,cl ;BCD码移到高半字节 or al,ah ;组合成压缩BCD码 mov dh,al ;存入dh寄..

必考:(3)编写一个程序段,在DX高4位全为0时,使AX = 0;否则使AX = -1。

tes dx,0f000h jz zero mov ax,-1 jmp done zero: mov ax,0

done: ret

〔习题2.34〕补充例2.40,当有溢出时显示“Error! Overflow!”,无溢出时显示“OK”。〔解答〕

okmsg db ?OK?, ?$?

errmsg db ?Error ! Overflow !?, ?$? … mov ax,X sub ax,Y jo overflow

mov dx,offset okmsg jmp next overflow: mov dx,errmsg next: mov ah,9 int 21h 错误解答:

mov ax,X sub ax,Y jo overflow

mov dx,offset okmsg okmsg db ?OK?, ?$?

mov dx,errmsg ;错误1:数据定义在代码中

mov ah,9 int 21h

overflow: errmsg db ?Error ! Overflow !?, ?$?

mov dx,errmsg ; 错误2:缺少JMP指令

mov ah,9 int 21h

必考:习题3.1〕伪指令语句与硬指令语句的本质区别是什么?伪指令有什么主要作用?

〔解答〕

伪指令语句与硬指令语句的本质区别是能不能产生CPU动作;

伪指令的作用是完成对如存储模式、主存变量、子程序、宏及段定义等很多不产生CPU动作的说明,并在程序执行前由汇编程序完成处理。

必考:〔习题3.9〕假设myword是一个字变量,mybyte1和mybyte2是两个字节变量,指出下列语句中的错误原因。(1) mov byte ptr [bx],1000

(2) mov bx,offset myword[si] (3) cmp mybyte1,mybyte2 (4) mov al,mybyte1+mybyte2 (5) sub al,myword (6) jnz myword 〔解答〕

(1)1000超出了一个字节范围

(2)寄存器的值只有程序执行时才能确定,而offset是汇编过程计算的偏移地址,故无法确定,改为lea bx,myword[si]

(3)两个都是存储单元,指令不允许

(4)变量值只有执行时才确定,汇编过程不能计算 (5)字节量AL与字量myword,类型不匹配

(6)Jcc指令只有相对寻址方式,不支持间接寻址方式

〔习题3.11〕给出下列语句中,指令立即数(数值表达式)的值:(1) mov al,23h AND 45h OR 67h

(2) mov ax,1234h/16+10h

(3) mov ax,NOT(65535 XOR 1234h) (4) mov al,LOW 1234h OR HIGH 5678h (5) mov ax,23h SHL 4

(6) mov ax,1234h SHR 6 (7) mov al,?a? AND (NOT(?a?-?A?)) (8) mov al,?H? OR 00100000b

(9) mov ax,(76543 LT 32768) XOR 7654h 〔解答〕

注:对于逻辑运算,有关操作数可化为二进制数。 (1)67h (2)133h (3)1234h (4)76h (5)0234h (6)0048h (7)41h (8)68h (9)7654h

必考〔习题3.15〕请设置一个数据段mydataseg,按照如下要求定义变量:(1) my1b为字符串变量:Personal Computer

(2) my2b为用十进制数表示的字节变量:20 (3) my3b为用十六进制数表示的字节变量:20 (4) my4b为用二进制数表示的字节变量:20 (5) my5w为20个未赋值的字变量 (6) my6c为100的常量

(7) my7c表示字符串:Personal Computer 〔解答〕

mydataseg segment

my1b db ?Personal Computer? my2b db 20

my3b db 14h ;20h my4b db 00010100b my5w dw 20 dup(?)

my6c equ 100 ;my6c = 100 my7c equ mydataseg ends

〔习题3.25〕按下面要求写一个简化段定义格式的源程序(1) 定义常量num,其值为5;数据段中定义字数组变量datalist,它的头5个字单元中依次存放-1、0、2、5和4,最后1个单元初值不定;

(2) 代码段中的程序将datalist中头num个数的累加和存入datalist的最后1个字单元中。

〔解答〕

.model small .stack .data num equ 5 datalist dw -1,0,2,5,4,? .code .startup

mov bx,offset datalist mov cx,num xor ax,ax

again: add ax,[bx] inc bx inc bx loop again

mov [bx],ax .exit 0 end

〔习题4.19〕编写计算100个正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示?overflow?。〔解答〕

.model small .stack .data num equ 100 wlist dw num dup(?) wordsum dw ? error db 'overflow. $' .code .startup

mov bx,offset wlist mov cx,num xor ax,ax again: add ax,[bx] jc next inc bx inc bx loop again mov [bx],ax jmp done next: mov dx,offset error mov ah,9

int 21h done: .exit 0 end

〔习题4.23〕子程序的参数传递有哪些方法,请简单比较。〔解答〕

寄存器、共享变量(公共存储单元)、堆栈

用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用; 用变量传递参数是主程序与被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。如果调用程序与被调用程序在同一个源程序文件中,只要设置好数据段寄存器DS,则子程序与主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序与被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;

用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。

〔习题4.24〕采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。〔解答〕

采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。

〔习题4.30〕设有一个数组存放学生的成绩(0 ~ 100),编制一个子程序统计0 ~ 59分、60 ~ 69分、70 ~ 79分、80 ~ 89分、90 ~ 100分的人数,并分别存放到scoreE、scoreD、score C、score B及score A单元中。编写一个主程序与之配合使用。〔解答〕

.model small .stack .data

score db 70,86,90,45,60,96,100,0,... ;全班成绩数组 count equ $-score ;总人数 scoreE db ? ;0--59分人数 scoreD db ? ;60--69分人数

scoreC db ? ;70--79分人数 scoreB db ? ;80--89分人数 scoreA db ? ;90--99分人数 .code .startup lea bx, score mov cx, count again:

mov al,[bx] ;取一个成绩 call tjrs ;调用统计分段人数 inc bx ;调整指针

loog again ;cx-cx-1,cx=0退出循环 .exit 0 tjrs proc ;统计分段人数 cmp al, 60

jae next0 ;al>= 60转

inc scoreE ;al<60,0--59分的人数加1 jmp next4 next0: cmp al, 70 jae next1 inc scoreD jmp next4 next1: cmp al, 80 jae next2 inc scoreC jmp next4

next2: cmp al, 90 jae next3 inc scoreB jmp next4 next3: inc scoreA next4: ret tjrs endp end

5.1; cmp X, 5 je abc jmp done abc: cmp ax, bx jne cde jmp done cde: inc ax done:.... 5.2;cmp X, 5 je abc jmp done cmp ax, bx jne abc jmp done abc: inc ax done: .... 5.4;

宏定义采用一对伪指令实现,格式如下(其中方括号表示可选): 宏名 macro [形参表] 宏定义体 endm

宏调用时,利用宏名带上实参即可,格式如下: 宏名 [实参表]

本文来源:https://www.bwwdw.com/article/vw0v.html

Top