文档库 最新最全的文档下载
当前位置:文档库 › 汇编语言课后习题答案 王爽主编

汇编语言课后习题答案 王爽主编

汇编语言课后习题答案 王爽主编
汇编语言课后习题答案 王爽主编

补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code

code segment

start: mov ax,2000h

mov ds,ax

mov bx,0

s: mov ch,0

mov cl,[bx]

jcxz ok ;当cx=0时,CS:IP指向OK

inc bx

jmp short s

ok: mov dx,bx

mov ax ,4c00h

int 21h

code ends

end start

检测点9.3

补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code

code segment

start: mov ax,2000h

mov ds,ax

mov bx,0

s:mov cl,[bx]

mov ch,0

inc cx

inc bx

loop s

ok:dec bx

mov dx,bx

mov ax,4c00h

int 21h

code ends

end start

书P101,执行loop s时,首先要将(cx)减1。

“loop 标号”相当于

dec cx

if((cx)≠0) jmp short 标号

检测点10.1

补全程序,实现从内存1000:0000处开始执行指令。

assume cs:code

stack segment

db 16 dup (0)

stack ends

code segment

start: mov ax,stack

mov ss,ax

mov sp,16

mov ax, 1000h

mov ax, 0

push ax

retf

code ends

end start

执行reft指令时,相当于进行:

pop ip

pop cs

根据栈先进后出原则,应先将段地址cs入栈,再将偏移地址ip入栈。

检测点10.3

下面的程序执行后,ax中的数值为多少?

内存地址机器码汇编指令执行后情况

1000:0 b8 00 00 mov ax,0 ax=0,ip指向1000:3

1000:3 9a 09 00 00 10 call far ptr s pop cs,pop ip,ip指向1000:9

1000:8 40 inc ax

1000:9 58 s:pop ax ax=8h

add ax,ax ax=10h

pop bx bx=1000h

add ax,bx ax=1010h

用debug进行跟踪确认,“call far ptr s”是先将该指令后的第一个字节段地址cs=1000h入栈,再将偏移地址ip=8h入栈,最后转到标号处执行指令。

出栈时,根据栈先进后出的原则,先出的为ip=8h,后出的为cs=1000h

检测点10.4

下面的程序执行后,ax中的数值为多少?

内存地址机器码汇编指令执行后情况

1000:0 b8 06 00 mov ax,6 ax=6,ip指向1000:3

1000:3 ff d0 call ax pop ip,ip指向1000:6

1000:5 40 inc ax

1000:6 58 mov bp,sp bp=sp=fffeh

add ax,[bp] ax=[6+ds:(fffeh)]=6+5=0bh

用debug进行跟踪确认,“call ax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈,再转到偏移地址为ax(16位reg)处执行指令。

检测点10.5

(1)下面的程序执行后,ax中的数值为多少?

assume cs:code

stack segment

dw 8 dup (0)

stack ends

code segment

start: mov ax,stack

mov ss,ax

mov sp,16

mov ds,ax

mov ax,0

call word ptr ds:[0eh]

inc ax

inc ax

mov ax,4c00h

int 21h

code ends

end start

推算:

执行call word ptr ds:[0eh]指令时,先cs入栈,再ip=11入栈,最后ip转移到(ds:[0eh])。(ds:[0eh])=11h,执行inc ax……最终ax=3

题中特别关照别用debug跟踪,跟踪结果不一定正确,但还是忍不住去试试,看是什么结果。

根据单步跟踪发现,执行call word ptr ds:[0eh]指令时,显示ds:[0eh]=065D。

ds:0000~ds:0010不是已设置成stack数据段了嘛,不是应该全都是0的嘛。

于是进行了更详细的单步跟踪,发现初始数据段中数据确实为0,但执行完mov ss,ax;mov sp,16这两条指令后,数据段中数据发生改变。这是为什么呢?中断呗~~~~

检测点10.5

(2)下面的程序执行后,ax和bx中的数值为多少?

assume cs:codesg

stack segment

dw 8 dup(0)

stack ends

codesg segment

start:

mov ax,stack

mov ss,ax

mov sp,10h

mov word ptr ss:[0],offset s ;(ss:[0])=1ah

mov ss:[2],cs ;(ss:[2])=cs

call dword ptr ss:[0] ;cs入栈,ip=19h入栈,转到cs:1ah处执行指令

;(ss:[4])=cs,(ss:[6])=ip

nop

s: mov ax,offset s ;ax=1ah

sub ax,ss:[0ch] ;ax=1ah-(ss:[0ch])=1ah-19h=1

mov bx,cs ;bx=cs=0c5bh

sub bx,ss:[0eh] ;bx=cs-cs=0

mov ax,4c00h

int 21h

codesg ends

end start

C:\DOCUME~1\ADMINI~1>debug jc10-5.exe

-u

0C5B:0000 B85A0C MOV AX,0C5A

0C5B:0003 8ED0 MOV SS,AX

0C5B:0005 BC1000 MOV SP,0010

0C5B:0008 36 SS:

0C5B:0009 C70600001A00 MOV WORD PTR [0000],001A

0C5B:000F 36 SS:

0C5B:0010 8C0E0200 MOV [0002],CS

0C5B:0014 36 SS:

0C5B:0015 FF1E0000 CALL FAR [0000]

0C5B:0019 90 NOP

0C5B:001A B81A00 MOV AX,001A

0C5B:001D 36 SS:

0C5B:001E 2B060C00 SUB AX,[000C]

-u

0C5B:0022 8CCB MOV BX,CS

0C5B:0024 36 SS:

0C5B:0025 2B1E0E00 SUB BX,[000E]

0C5B:0029 B8004C MOV AX,4C00

课程设计一

将实验7中的Power idea公司的数据按照图所示的格式在屏幕上显示现来

table segment

db '1975','1976','1977','1978','1979','1980','1981','1982','1983'

db '1984','1985','1986','1987','1988','1989','1990','1991','1992'

db '1993','1994','1995'

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514

dd 345980,590827,803530,1183000,1843000,2795000,3753000,4649000,5937000 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226

dw 11542,14430,15257,17800

dw 5,3,42,104,85,210,123,111,105,125,140,136,153,211,199,209,224,239

dw 260,304,333

table ends

data segment

db 32 dup (0)

data ends

code segment

start: mov ax,data

mov ds,ax

mov ax,table

mov es,ax

mov bx,0

mov si,0

mov di,0

mov cx,21

mov dh,2

mov dl,30

g: push cx

push dx

mov ax,es:[bx]

mov [si],ax

mov ax,es:[bx].2

mov [si].2,ax ;年份入ds:si

add si,6

mov ax,es:[bx].84

mov dx,es:[bx].86

call dtoc2 ;收入转成十进制字符入ds:si

add si,10

mov ax,es:[di].168

mov dx,0

call dtoc2 ;人员数转成十进制字符入ds:si

add si,6

mov ax,es:[di].210

mov dx,0

call dtoc2 ;人均收入转成十进制字符入ds:si

mov si,0 ;设置ds:si指向需显示字符首地址

b: mov cx,29

c: push cx

mov cl,[si]

jcxz f ;(ds:si)=0转到f执行

d: inc si

pop cx

loop c

inc si

mov al,0

mov [si],al ;设置结尾符0

mov si,0 ;设置ds:si指向需显示字符首地址

pop dx

mov cl,2

call show_str

add bx,4 ;dword数据指向下一数据单元

add di,2 ;word数据指向下一数据单元

add dh,1 ;指向显存下一行

pop cx

loop g

mov ax,4c00h

int 21h

f: mov al,20h

mov [si],al ;(ds:si)=0的数据改成空格

jmp d

;名称:dtoc2

;功能:将dword型数据转变为表示十进制的字符串,字符串以0为结尾符。;参数:(ax)=dword型数据的低16位;

; (dx)=dword型数据的高16位;

; ds:si指向字符串首地址。

;返回:无。

dtoc2:

push ax

push bx

push cx

push dx

push si

push di

mov di,0

d20: mov cx,10 ;除数为10

call divdw

add cx,30h ;余数+30h,转为字符

push cx ;字符入栈

inc di ;记录字符个数

mov cx,ax

jcxz d21 ;低位商=0时,转到d21检测高位商

jmp d20

d21: mov cx,dx

jcxz d22 ;高低位商全=0时,转到d22执行

jmp d20

d22: mov cx,di

d23: pop ax ;字符出栈

mov [si],al

inc si ;ds:si指向下一单元

loop d23

mov al,0

mov [si],al ;设置结尾符0

pop di

pop si

pop dx

pop cx

pop bx

pop ax

ret

;名称:divdw

;功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。;参数:(ax)=dword型数据的低16位;

; (dx)=dword型数据的高16位;

; (cx)=除数。

;返回:(dx)=结果的高16位;

; (ax)=结果的低16位;

; (cx)=余数。

divdw:

push si

push bx

push ax

mov ax,dx

mov dx,0

div cx ;被除数的高位/cx

mov si,ax

pop ax

div cx ;(被除数高位的商+低位)/cx

mov cx,dx ;余数入cx

mov dx,si ;高位的商入dx

pop bx

pop si

ret

;名称:show_str

;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。

;参数:(dh)=行号(取值范围0~24);

; (dl)=列号(取值范围0~79);

; (cl)=颜色;

; ds:si指向字符串的首地址。

;返回:无。

show_str:

push ax

push bx

push es

push si

mov ax,0b800h

mov es,ax

mov ax,160

mul dh

mov bx,ax ;bx=160*dh

mov ax,2

mul dl ;ax=dl*2

add bx,ax ;mov bx,(160*dh+dl*2)设置es:bx指向显存首地址

mov al,cl ;把颜色cl赋值al

mov cl,0

show0:

mov ch,[si]

jcxz show1 ;(ds:si)=0时,转到show1执行

mov es:[bx],ch

mov es:[bx].1,al

inc si ;ds:si指向下一个字符地址

add bx,2 ;es:bx指向下一个显存地址

jmp show0

show1:

pop si

pop es

pop bx

pop ax

ret

code ends

end start

检测点11.1

写出下面每条指令执行后,ZF、PF、SF、等标志位的值。

sub al,al al=0h ZF=1 PF=1 SF=0

mov al,1 al=1h ZF=1 PF=1 SF=0

push ax ax=1h ZF=1 PF=1 SF=0

pop bx bx=1h ZF=1 PF=1 SF=0

add al,bl al=2h ZF=0 PF=0 SF=0

add al,10 al=12h ZF=0 PF=1 SF=0

mul al ax=144h ZF=0 PF=1 SF=0

检测点涉及的相关内容:

ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1

PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制中1的个数是否为偶数,结果为偶数时,PF=1

SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1

add、sub、mul、div 、inc、or、and等运算指令影响标志寄存器

mov、push、pop等传送指令对标志寄存器没影响。

检测点11.2

写出下面每条指令执行后,ZF、PF、SF、CF、OF等标志位的值。

al CF OF SF ZF PF

sub al,al 0h/0000 0000b 0 0 0 1 1

mov al,10h 10h/0010 0000b 0 0 0 1 1

add al,90h a0h/1010 0000b 0 0 1 0 1

mov al,80h 80h/1000 0000b 0 0 1 0 1

add al,80h 0h/0000 0000b 1 1 0 1 1

mov al,0fch 0fch/1111 1100b 1 1 0 1 1

add al,05h 1h/0000 0001b 1 0 0 0 0

mov al,7dh 7dh/1111 1101b 1 0 0 0 0

add al,0bh 88h/1000 1000b 0 1 1 0 1

检测点涉及的相关内容:

ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1

PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制数中1的个数是否为偶数,结果为偶数时,PF=1

SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1

CF是flag的第0位,进位标志位,记录无符号运算结果是否有进/借位,结果有进/借位时,SF=1

OF是flag的第11位,溢出标志位,记录有符号运算结果是否溢出,结果溢出时,OF=1

add、sub、mul、div 、inc、or、and等运算指令影响flag

mov、push、pop等传送指令对flag没影响

检测点11.3

(1)补全下面的程序,统计F000:0处32个字节中,大小在[32,128]的数据个数。

mov ax,0f000h

mov ds,ax

mov bx,0 ;ds:bx指向第一个字节

mov dx,0 ;初始化累加器

mov cx,32

s: mov al,[bx]

cmp al,32 ;和32进行比较

jb s0 ;如果低于al转到s0,继续循环

cmp al,128 ;和128进行比较

ja s0 ;如果高于al转到s0,继续循环

inc dx

s0: inc bx

loop s

[32,128]是闭区间,包括两端点的值

(32,128)是开区间,不包括两端点的值

检测点11.3

(2)补全下面的程序,统计F000:0处32个字节中,大小在(32,128)的数据个数。

mov ax,0f000h

mov ds,ax

mov bx,0 ;ds:bx指向第一个字节

mov dx,0 ;初始化累加器

mov cx,32

s: mov al,[bx]

cmp al,32 ;和32进行比较

jna s0 ;如果不高于al转到s0,继续循环

cmp al,128 ;和128进行比较

jnb s0 ;如果不低于al转到s0,继续循环

inc dx

s0: inc bx

loop s

[32,128]是闭区间,包括两端点的值

(32,128)是开区间,不包括两端点的值

检测点11.4

下面指令执行后,(ax)= 45h

mov ax,0

push ax

popf

mov ax,0fff0h

add ax,0010h

pushf

pop ax

and al,11000101B

and ah,00001000B

推算过程:

popf后,标志寄存器中,本章节介绍的那些标志位都为0(但是此时标志寄存器并不是所有位置都为0,这个不用关心,没学过的位置用*先代替),向下进行,那么pushf将计算后的当时状态的标志寄存器入栈,然后pop给ax,这是ax是寄存器的值(这个值中包含了我们的*号),接下来就是对那些没有学过的标志位的屏蔽操作,这就是最后两条指令的意义所在,将不确定的位置都归0,那么只剩下我们能够确定的位置了,所以,结果就可以推理出来了。

mov ax,0

push ax

popf

mov ax,0fff0h

add ax,0010h

pushf

pop ax 0 0 0 0 of df if tf sf zf 0 af 0 pf 0 cf

0 0 0 0 0 0 * * 0 1 0 * 0 1 0 1 ax=flag=000000** 010*0101b

and al,11000101B al=01000101b=45h

and ah,00001000B ah=00000000b=0h

C:\DOCUME~1\SNUSER>debug

-a

0BF9:0100 mov ax,0

0BF9:0103 push ax

0BF9:0104 popf

0BF9:0105 mov ax,fff0

0BF9:0108 add ax,10

0BF9:010B pushf

0BF9:010C pop ax

0BF9:010D and al,c5

0BF9:010F and ah,8

0BF9:0112

-r

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0100 NV UP EI PL NZ NA PO NC 0BF9:0100 B80000 MOV AX,0000

-t

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0103 NV UP EI PL NZ NA PO NC 0BF9:0103 50 PUSH AX

-t

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEC BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0104 NV UP EI PL NZ NA PO NC 0BF9:0104 9D POPF

-t

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0105 NV UP DI PL NZ NA PO NC 0BF9:0105 B8F0FF MOV AX,FFF0

-t

AX=FFF0 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0108 NV UP DI PL NZ NA PO NC 0BF9:0108 051000 ADD AX,0010

-t

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=010B NV UP DI PL ZR NA PE CY 0BF9:010B 9C PUSHF

-t

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEC BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=010C NV UP DI PL ZR NA PE CY 0BF9:010C 58 POP AX

-t

AX=3047 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=010D NV UP DI PL ZR NA PE CY 0BF9:010D 24C5 AND AL,C5

-t

AX=3045 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=010F NV UP DI PL NZ NA PO NC 0BF9:010F 80E408 AND AH,08

-t

AX=0045 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0BF9 ES=0BF9 SS=0BF9 CS=0BF9 IP=0112 NV UP DI PL ZR NA PE NC 0BF9:0112 4C DEC SP

(1)用debug查看内存,情况如下:

0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00

则3号中断源对应的中断处理程序入口的偏移地址的内存单位的地址为: 0070:018b

检测点涉及相关内容:

一个表项存放一个中断向量,也就是一个中断处理程序的入口地址,这个入口地址包括段地址和偏移地址,一个表项占两个字,高地址存放段地址,低地址存放偏移地址

检测点12.1

(2)

存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为: 4N

存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为: 4N+2

检测点涉及相关内容:

一个表项存放一个中断向量,也就是一个中断处理程序的入口地址,这个入口地址包括段地址和偏移地址,一个表项占两个字,高地址存放段地址,低地址存放偏移地址

实验11(letterc子程序)小写改成大写

编写一个子程序,将包含任意字符,以0结尾的字符串的小写字母转变成大写字母

程序一:此题为小写改成大写,根据书P141页介绍,小写字母'a'-'z'对应ASCII码为61h-86h,只要[61,86]这段区间里的ASCII减去20h,就改成了大写字母。

assume cs:codesg

datasg segment

db "Seginner's All-purpose Symbolic Instruction Code.",'0'

datasg ends

codesg segment

begin:

mov ax,datasg

mov ds,ax

mov si,0 ;ds:si指向第一个字节

call letterc

mov ax,4c00h

int 21h

;名称:letterc

;功能:将以0结尾的字符中的小写字母转变成大写字母

;参数:ds:si指向字符串首地址

letterc:push ax

push si

let: cmp byte ptr [si],0 ;和0进行比较

je let0 ;如果等于0则转到let0,结束

cmp byte ptr [si],61h ;和61h进行比较

jb let1 ;如果低于60h则转到let1,继续循环

cmp byte ptr [si],86h ;和86h进行比较

ja let1 ;如果高于86h则转到let1,继续循环

mov al,[si]

sub al,20h ;转为大写字母

mov [si],al

let1:

inc si

jmp let

let0:

pop ax

ret

codesg ends

end begin

------------------------华丽的分割线----------------------------

程序二:参考书中P143页内容,有更好的办法,无需用到寄存器。

可以用and直接修改内存,将ASCII码的第5位置为0,变为大写字母。

assume cs:codesg

datasg segment

db "Seginner's All-purpose Symbolic Instruction Code.",'0'

datasg ends

codesg segment

begin: mov ax,datasg

mov ds,ax

mov si,0 ;ds:si指向第一个字节

call letterc

mov ax,4c00h

int 21h

;名称:letterc

;功能:将以0结尾的字符中的小写字母转变成大写字母

;参数:ds:si指向字符串首地址

letterc:push si

let: cmp byte ptr [si],0 ;和0进行比较

je let0 ;如果等于0则转到let0,结束

cmp byte ptr [si],61h ;和61h进行比较

jb let1 ;如果低于60h则转到let1,继续循环

cmp byte ptr [si],86h ;和86h进行比较

ja let1 ;如果高于86h则转到let1,继续循环

and byte ptr [si],11011111b ;ASCII码的第5位置为0,转为大写

let1:

inc si

jmp let

let0:

pop si

ret

codesg ends

end begin

检测点13.1

7ch中断例程如下:

lp: push bp

mov bp,sp

dec cx

jcxz lpret

add [bp+2],bx

lpret: pop bp

iret

(1)在上面的内容中,我们用7ch中断例程实现loop的功能,则上面的7ch中断例程所能进行的最大转移位移是多少?

最大位移是FFFFH

(2)用7ch中断例程完成jmp near ptr s指令功能,用bx向中断例程传送转移位移。

应用举例:在屏幕的第12行,显示data段中以0结尾的字符串。

assume cs:code

data segment

db 'conversation',0

data ends

code segment

start:

mov ax,data

mov ds,ax

mov si,0

mov ax,0b800h

mov es,ax

mov di,12*160

s: cmp byte ptr [si],0

je ok

mov al,[si]

mov es:[di],al

inc si

add di,2

mov bx,offset s-offset ok

int 7ch

ok: mov ax,4c00h

int 21h

code ends

end start

jmp near ptr s指令的功能为:(ip)=(ip)+16位移,实现段内近转移

检测点13.2

判断下面说法的正误:

(1)我们可以编程改变FFFF:0处的指令,使得CPU不去执行BIOS中的硬件系统检测和初始化程序。答:错误,FFFF:0处的内容无法改变。

检测点13.2

判断下面说法的正误:

(2)int 19h中断例程,可以由DOS提供。

答:错误,先调用int 19h,后启动DOS。

实验13

(1)编写并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处。;名称:int 7ch中断例程

;功能:显示一个0结束的字符串,中断例程安装在0:200处

;参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si指向字符串首地址

assume cs:code

code segment

start: mov ax,cs

mov ds,ax

mov si,offset show_str ;设置ds:si指向源地址

mov ax,0

mov es,ax

mov di,200h ;设置es:di指向目标地址

mov cx,offset show_strend-offset show_str ;设置cx为传输长度 cld ;设置传输方向为正

rep movsb

mov ax,0

mov es,ax

mov word ptr es:[7ch*4],200h

mov word ptr es:[7ch*4+2],0 ;设置中断向量表

mov ax,4c00h

int 21h

;名称:show_str

;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。

;参数:(dh)=行号(取值范围0~24);

; (dl)=列号(取值范围0~79);

; (cl)=颜色;

; ds:si指向字符串的首地址。

;返回:无。

show_str:push ax

push bx

push es

push si

mov ax,0b800h

mov es,ax

mov ax,160

mul dh

mov bx,ax ;bx=160*dh

mov ax,2

mul dl ;ax=dl*2

add bx,ax ;mov bx,(160*dh+dl*2)设置es:bx指向显存首地址 mov al,cl ;把颜色cl赋值al

mov cl,0

show0: mov ch,[si]

jcxz show1 ;(ds:si)=0时,转到show1执行

mov es:[bx],ch

mov es:[bx].1,al

inc si ;ds:si指向下一个字符地址

add bx,2 ;es:bx指向下一个显存地址

jmp show0

show1: pop si

pop es

pop bx

pop ax

iret

mov ax,4c00h

int 21h

show_strend:nop

code ends

end start

;实验13(1)应用举例

assume cs:code

data segment

db 'welcome to masm!',0

data ends

code segment

start: mov dh,10

mov dl,10

mov cl,2

mov ax,data

mov ds,ax

mov si,0

int 7ch

mov ax,4c00h

int 21h

code ends

end start

实验13

(2)编写并安装int 7ch中断例程,功能为完成loop指令功能

;名称:int 7ch中断例程

;功能:完成loop指令功能,中断例程安装在0:200处

;参数:(cx)=循环次数,(bx)=位移

assume cs:code

code segment

start: mov ax,cs

mov ds,ax

mov si,offset lp ;设置ds:si指向源地址

mov ax,0

mov es,ax

mov di,200h ;设置es:di指向目标地址

mov cx,offset lpend-offset lp ;设置cx为传输长度

cld ;设置传输方向为正

rep movsb

mov ax,0

mov es,ax

mov word ptr es:[7ch*4],200h

mov word ptr es:[7ch*4+2],0 ;设置中断向量表

mov ax,4c00h

int 21h

lp: push bp

mov bp,sp

dec cx

jcxz lpret

add [bp+2],bx

lpret: pop bp

iret

mov ax,4c00h

int 21h

lpend:nop

code ends

end start

;实验13(2)应用举例

assume cs:code

code segment

start: mov ax,0b800h

mov es,ax

mov di,160*12

mov bx,offset s-offset se ;设置从标号se到标号s的转移位移 mov cx,80

s: mov byte ptr es:[di],'!'

add di,2

int 7ch ;(cx)≠0,转移到标号s处

se: nop

mov ax,4c00h

int 21h

code ends

end start

实验13

(3)下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全代码。assume cs:code

code segment

s1: db 'Good,better,best,','$'

s2: db 'Never let it rest,','$'

s3: db 'Till good is better,','$'

s4: db 'And better,best.','$'

s : dw offset s1,offset s2,offset s3,offset s4

row: db 2,4,6,8

start: mov ax,cs

mov ds,ax

mov bx,offset s

mov si,offset row

mov cx,4

ok: mov bh,0 ;第0页

mov dh,[si] ;dh中放行号

mov dl,0 ;dl中放列号

mov ah,2 ;置光标

int 10h

mov dx,[bx] ;ds:dx指向字符串首地址

mov ah,9 ;在光标位置显示字符

int 21h

inc si ;行号递增

add bx,2 ;指向下一字符串

loop ok

mov ax,4c00h

int 21h

code ends

end start

检测点14.1 读取写入CMOS RAM单元内容

(1)编程,读取CMOS RAM的2号单元内容。

assume cs:code

code segment

start: mov al,2 ;赋值al

out 70h,al ;将al送入端口70h

in al,71h ;从端口71h处读出单元内容

mov ax,4c00h

int 21h

code ends

end start

检测点14.1

(2)编程,向CMOS RAM的2号单元写入0。

assume cs:code

code segment

start: mov al,2 ;赋值al

out 70h,al ;将al送入端口70h

mov al,0 ;赋值al

out 71h,al ;向端口71h写入数据al

mov ax,4c00h

int 21h

code ends

end start

检测点14.2 用加法和移位指令计算

编程,用加法和移位指令计算(ax)=(ax)*10

提示:(ax)*10=(ax)*2+(ax)*8

assume cs:code

code segment

start: mov bx,ax

shl ax,1 ;左移1位(ax)=(ax)*2

mov cl,3

shl bx,cl ;左移3位(bx)=(ax)*8

add ax,bx ;(ax)=(ax)*2+(ax)*8

mov ax,4c00h

int 21h

code ends

end start

;应用举例:计算ffh*10

assume cs:code

code segment

start: mov ax,0ffh

mov bx,ax

shl ax,1 ;左移1位(ax)=(ax)*2

mov cl,3

shl bx,cl ;左移3位(bx)=(ax)*8

add ax,bx ;(ax)=(ax)*2+(ax)*8

mov ax,4c00h

int 21h

code ends

end start

PS:

左移1位,N=(N)*2

左移2位,N=(N)*4

左移3位,N=(N)*8

左移4位,N=(N)*16

左移5位,N=(N)*32

实验14 访问CMOS RAM

编程,以“年/月/日时:分:秒”的格式,显示当前的日期、时间。(两个程序程序一:

assume cs:code

code segment

start: mov ax,0

mov al,9

mov si,0

mov cx,6

s: push cx

push ax

out 70h,al ;将al送入端口70h

in al,71h ;从端口71h处读出单元内容

mov ah,al

mov cl,4

shr ah,cl

and al,00001111b ;al分成两个表示BCD码值的数据

add ah,30h

add al,30h ;BCD码+30h=10进制数对应的ASCII码

mov bx,0b800h

mov es,bx

mov byte ptr es:[160*12+40*2][si],ah ;显示十位数码

mov byte ptr es:[160*12+40*2+2][si],al ;显示个位数码

pop ax

dec ax ;指向前一数据单元

jmp s1

s0: pop cx

add si,6

loop s

mov ax,4c00h

int 21h

s1: cmp ax,10

ja s0

cmp ax,0

je s0

cmp ax,6

ja s2 ;ax>6,为年/月/日

je s3 ;ax=6,为日结尾

jb s4 ;ax<6,为时:分:秒

s2: mov byte ptr es:[160*12+40*2+4][si],'/' ;添加'/'

jmp s0

s3: sub ax,2

jmp s0

s4: sub ax,1

mov byte ptr es:[160*12+40*2+4][si],':' ;添加':'

jmp s0

code ends

end start

==============================华丽的分割线=============================== 程序二:

assume cs:code

code segment

time db 'yy/mm/dd hh:mm:ss','$'

cmos db 9,8,7,4,2,0

start: mov ax,cs

mov ds,ax

mov bx,0

mov si,0

mov cx,6

a: push cx

mov al,cmos[bx]

out 70h,al ;将al送入地址端口70h

in al,71h ;从数据端口71h处读出单元内容

mov ah,al

mov cl,4

shr al,cl ;右移4位

and ah,0fh ;al分成两个表示BCD码值的数据

add ax,3030h ;BCD码+30h=10进制数对应的ASCII码

mov cs:[si],ax ;ASCII码写入time段

inc bx

add si,3

pop cx

loop a

;名称:BIOS中断(int 10h)

;功能:(ah)=2置光标到屏幕指定位置、(ah)=9在光标位置显示字符

;参数:(al)=字符、(bh)=页数、(dh)=行号、(dl)=例号

; (bl)=颜色属性、(cx)=字符重复个数

mov ah,2 ;置光标

mov bh,0 ;第0页

mov dh,13 ;dh中放行号

mov dl,32 ;dl中放例号

int 10h

;名称:DOS中断(int 21h)

;功能:(ah)=9显示用'$'结束的字符串、(ah)=4ch程序返回

;参数:ds:dx指向字符串、(al)=返回值

mov dx,0

mov ah,9

int 21h

;结束

mov ax,4c00h

int 21h

code ends

end start

检测点15.1

(1)仔细分析一下书中的in9中断例程,看看是否可以精简一下?

其实在我们的int 9中断例程中,模拟int指令调用原int 9中断例程的程序段是可以精简的,因为在进入中断例程后,IF和TF都已置0,没有必要再进行设置了,对于程序段:

pushf ;标志寄存器入栈

pushf

pop bx

and bh,11111100b ;IF和TF为flag的第9位和第8位

push bx

popf ;TF=0,IF=0

call dword ptr ds:[0] ;CS、IP入栈;(IP)=ds:[0],(CS)=ds:[2]

可以精简为:

pushf ;标志寄存器入栈

call dword ptr ds:[0] ;CS、IP入栈;(IP)=ds:[0],(CS)=ds:[2]

两条指令。

检测点15.1

(2)仔细分析程序中的主程序,看看有什么潜在的问题?

在主程序中,如果在设置执行设置int 9中断例程的段地址和偏移地址的指令之间发生了键盘中段,则CPU 将转去一个错误的地址执行,将发生错误。

找出这样的程序段,改写他们,排除潜在的问题。

;在中断向量表中设置新的int 9中断例程的入口地址

cli ;设置IF=0屏蔽中断

mov word ptr es:[9*4],offset int9

mov es:[9*4+2],cs

sti ;设置IF=1不屏蔽中断

============更改后的int 9中断例程================

;功能:在屏幕中间依次显示'a'~'z',并让人看清。在显示过程中按下Esc键后,改变显示的颜色。assume cs:code

stack segment

db 128 dup (0)

stack ends

data segment

dw 0,0

data ends

code segment

start: mov ax,stack

mov ss,ax

mov sp,128

;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中

mov ax,data

mov ds,ax

mov ax,0

mov es,ax

push es:[9*4]

pop ds:[0]

push es:[9*4+2]

pop ds:[2]

;在中断向量表中设置新的int 9中断例程的入口地址

cli ;设置IF=0屏蔽中断

mov word ptr es:[9*4],offset int9

mov word ptr es:[9*4+2],cs

sti ;设置IF=1不屏蔽中断

;依次显示'a'~'z'

mov ax,0b800h

mov es,ax

mov ah,'a'

s: mov es:[160*12+40*2],ah ;第12行第40列

inc ah

cmp ah,'z'

jnb s

;将中断向量表中int 9中断例程的入口恢复为原来的地址

mov ax,0

mov es,ax

push ds:[0]

pop ss:[9*4]

push ds:[2]

pop es:[9*4+2]

;结束

mov ax,4c00h

int 21h

;循环延时,循环100000h次

delay: push ax

push dx

mov dx,1000h

mov ax,0

delay1: sub ax,1

sbb dx,0 ;(dx)=(dx)-0-CF

cmp ax,0

jne delay1

cmp dx,0

jne delay1

pop dx

pop ax

ret

;以下为新的int 9中断例程

int9: push ax

push bx

push es

in al,60h ;从端口60h读出键盘输入

;对int指令进行模拟,调用原来的int 9中断例程

pushf ;标志寄存器入栈

call dword ptr ds:[0] ;CS、IP入栈;(IP)=ds:[0],(CS)=ds:[2]

;如果是ESC扫描码,改变显示颜色

cmp al,1 ;和esc的扫描码01比较

jne int9ret ;不等于esc时转移

mov ax,0b800h

mov es,ax

inc byte ptr es:[160*12+40*2+1] ;将属性值+1,改变颜色

int9ret:pop es

pop bx

pop ax

iret

code ends

end start

实验15 安装新的int 9中断例程(按'A'键后显示满屏幕的'A')

任务:安装一个新的int 9中断例程

;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕的'A',其他键照常处理assume cs:code

stack segment

db 128 dup (0)

stack ends

code segment

start: mov ax,stack

mov ss,ax

mov sp,128

push cs

pop ds

mov ax,0

mov es,ax

mov si,offset int9 ;设置ds:si指向源地址

mov di,204h ;设置es:di指向目标地址

汇编语言 第二版 王爽 完整答案

第1章基础知识 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为13。 (2)1KB的存储器有1024个存储单元。存储单元的编号从0到1023。 (3)1KB的存储器可以存储1024*8个bit,1024个Byte。 (4)1GB、1MB、1KB分别是2^30、2^20、2^10 Byte。(n^m的意思是n的m次幂) (5)8080、8088、80286、80386的地址总线宽度分别是16根、20根、24根、32根,则它们的寻址能力分别为:64(KB)、1(MB)、16(MB)、4(GB)。 (6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为:1(B)、1(B)、2(B)、2(B)、4(B)。 (7)从内存中读取1024字节的数据,8086至少要读512次、80386至少要读256次。 (8)在存储器中,数据和程序以二进制形式存放。 第2章寄存器答案 检测点2.1 (1) 写出每条汇编指令执行后相关寄存器中的值。 mov ax,62627 AX=F4A3H mov ah,31H AX=31A3H mov al,23H AX=3123H add ax,ax AX=6246H mov bx,826CH BX=826CH mov cx,ax CX=6246H mov ax,bx AX=826CH add ax,bx AX=04D8H mov al,bh AX=0482H mov ah,bl AX=6C82H add ah,ah AX=D882H add al,6 AX=D888H add al,al AX=D810H mov ax,cx AX=6246H (2) 只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。 解: mov ax,2 add ax,ax add ax,ax add ax,ax 检测点2.2 (1) 给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为00010H到1000FH。 (2) 有一数据存放在内存 20000H 单元中,先给定段地址为SA,若想用偏移地址寻到此单元。

王爽《汇编语言》第1章DOC版

第1章基础知识 汇编语言是直接在硬件之上工作的编程语言,首先要了解硬件系统的结构,才能有效地应用汇编语言对其编程。在本章中,对硬件系统结构的问题进行一部分的探讨,以使后续的课程可在一个好的基础上进行。当课程进行到需要补充新的基础知识(关于编程结构或其他的)时候,再对相关的基础知识进行介绍和探讨。本书的原则是,以后用到的知识,以后再说。 在汇编课程中不对硬件系统进行全面和深入的研究,因为这不在本课程的范围之内。关于PC机及CPU物理结构和编程结构的全面研究,在《微机原理与接口》中进行;对于计算机一般的结构、功能、性能的研究在一门称为《组成原理》的理论层次更高的课程中进行。汇编课程的研究重点放在如何利用硬件系统的编程结构和指令集有效灵活地控制系统进行工作。 1.1 机器语言 说到汇编语言的产生,首先要讲一下机器语言。机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。 上面所说的计算机指的是可以执行机器指令,进行运算的机器。这是早期计算机的概念。现在,在常用的PC机中,有一个芯片来完成上面所说的计算机的功能。这个芯片就是我们常说的CPU(Central Processing Unit,中央处理单元),CPU是一种微处理器。以后我们提到的计算机是指由CPU和其他受CPU直接或间接控制的芯片、器件、设备组成的计算机系统,比如我们最常见的PC机。 每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使它工作。所以每一种微处理器都有自已的机器指令集,也就是机器语言。 早期的程序设计均使用机器语言。程序员们将用0、1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。 应用8086CPU完成运算s=768+12288-1280,机器码如下: 101100000000000000000011 000001010000000000110000 001011010000000000000101 假如将程序错写成以下这样,请读者找出错误。 101100000000000000000011 000001010000000000110000 000101101000000000000101

汇编语言-王爽-完美高清版视频教程

汇编语言》-王爽-完美高清版-零基础汇编语言入门书籍PDF格式 同时按ctrl+要下载的地址既可下载对应的视频 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f61cb107c8 001第一章- 基础知识01 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6806f45b8 002第一章- 基础知识02 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6ec42d4d3 003第一章- 基础知识03 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6deb05ec4 004第一章-基础知识04 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6e51f6838 005第一章- 基础知识05 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f66edaf8d3 006第二章- 寄存器(CPU工作原理)01 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6d07e07b9 007第二章- 寄存器(CPU工作原理)02 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6d7f585a8 008第二章- 寄存器(CPU工作原理)03 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f639d8b3cf 009第二章- 寄存器(CPU工作原理)04 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6dcadbde6 010第二章- 寄存器(CPU工作原理)05 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6ea3f01c1 011第二章- 寄存器(CPU工作原理)06 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f65b96a06f 012第二章- 寄存器(CPU工作原理)07 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f682da085a 013第三章- 寄存器(内存访问)01 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6486e698 014第三章- 寄存器(内存访问)02 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6b7491d9f 015第三章- 寄存器(内存访问)03 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f622b7f9a7 016第三章- 寄存器(内存访问)04 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f64e2424b9 017第三章- 寄存器(内存访问)05 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6e5132d4d 018第三章- 寄存器(内存访问)06 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f655c10e86 019第三章- 寄存器(内存访问)07 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6b22e64e6 020第四章- 第一个程序01 下载地址:https://www.wendangku.net/doc/3d6095797.html,/file/f6812126a4

汇编语言王爽第二版课后答案

第一章基础知识 检测点1.1(第8页) ---------------------- (1) 13 (2) 1024,0,1023 (3) 8192,1024 (4) 2^30,2^20,2^10 (5) 64,1,16,4 (6) 1,1,2,2,4 (7) 512,256 (8) 二进制 注意: 1.第4题中的符号'^'指求幂运算(如: 2^30指2的30次方) 第二章寄存器(CPU工作原理) 检测点2.1(第18页) ---------------------- (1)写出每条汇编指令执行后相关寄存器中的值。第一空:F4A3H 第二空:31A3H 第三空:3123H 第四空:6246H 第五空:826CH 第六空:6246H 第七空:826CH 第八空:04D8H 第九空:0482H 第十空:6C82H 第十一空:D882H 第十二空:D888H 第十三空:D810H 第十四空:6246H (2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。 解答如下: mov ax,2 add ax,ax add ax,ax add ax,ax 检测点2.2(第23页) ---------------------- (1)00010H,1000FH (2)1001H,2000H 第2题说明: 因为段的起始地址要为16的倍数。所以当段地址小于1001H或大于2000H时CPU都无法寻到。 检测点2.3(第33页) ----------------------答:CPU修改了4次IP的值。 情况如下: 第1次:执行完mov ax,bx后 第2次:执行完sub ax,ax后 第3次:读入jmp ax后 第4次:执行完jmp ax后 最后IP的值为0 实验1 查看CPU和内存,用机器指令和汇编指令编程(第33页) ----------------------------------------------------- 1.预备知识:Debug的使用 <此部分略> 2.实验任务(第43页) (1) <此部分略> (2) <此部分略> (3) 通过DEBUG中的D命令查看到主板的生产日期[以月、日、年,分隔符为'/'的格式]存储在内存ffff:0005~ffff:000C(共8个字节单元中)处。此生产日期不能被改变,因为其具有‘只读’属性。 (4) 通过向内存中的显存写入数据,使计算机根据写入的数据进行ASCII转换,并将转换后且可打印的字符输出到屏幕上。<注:关于显存的详细讨论不在此题范围> 第三章寄存器(内存访问) 检测点3.1(第52页) ---------------------- (1)(题目:略) 第一空:2662H 第二空:E626H 第三空:E626H 第四空:2662H 第五空:D6E6H 第六空:FD48H 第七空:2C14H 第八空:0000H 第九空:00E6H 第十空:0000H 第十一空:0026H 第十二空:000CH 提示:此题可在DEBUG中利用E命令在本机上按照题目中所给出的内存单元及其数据进行相应地修改,然后再用A命令进行写入(题目中所给出的)相应的汇编指令,最后再进行T命令进行逐步执行,以查看相应结果。

汇编语言(第2版)王爽著 课后实验报告详解

汇编语言实验报告 : 班级学号 学生姓名 提交日期 成 绩

实验1-1如下: 用E命令将指令写入内存:

用A命令将指令写入内存: 实验1-2代码如下: 用a命令在2000:0000处写如要写如的代码,然后用R命令来修改CS为2000,IP修改为0,然后用T命令执行,直到AX中的值为10,因为是默认为十六进制,所以ax中的0010实际代表十进制的16。如图:

实验1-3: 用D 命令输入内存fff0h~fffffh,则可看到:

生产日期为06/15/09在地址为FFFF5~FFFF12处,现在用E命令随便修改一下有: 在window7下虚拟的dos中可以改,但如果重新打开dos中的debug 则日期任然不会改变,因为那是ROM。 实验1-4代码如下:

内存地址为B800:0开始的为显存,是RAM,可以改变其值来在屏幕中显示,其中这一个字符占两个字节,前一个(低)为字符的ASCII 码,后一个(高)为要显示的颜色,内存B800:0和B800:1这两个字节对应着屏幕中的第一个字符的位置,依次类推,每个屏幕的行有80个字符,对应的内存占160个字节 实验2-1:(按实验结果填空) Mov ax,ffff Mov ds,ax Mov ax,2200 Mov ss,ax Mov sp,0100 Mov ax,[0] ;ax=5BEA Add ax,[2] ;ax=5CCA Mov bx,[4] ;bx=30F0 Add bx,[6] ;bx=6026 Push ax ;sp=00FE; 修改的内存单元的地址是2200:00FE 内容是5CCA Push bx ;sp=00FC; 修改的内存单元的地址是2200:00FC内容是6026 Pop ax ;sp=00FE; ax=6026. Pop bx ;sp=0100; bx=.5CCA Push [4] ;sp=00FE; 修改的内存单元的地址是2200:00FE内容是30F0 Push [6] ;sp=00FC; 修改的内存单元的地址是2200:00FC内容是2F36 实验截图如下:

汇编语言课后习题答案 王爽主编

补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。 assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s: mov ch,0 mov cl,[bx] jcxz ok ;当cx=0时,CS:IP指向OK inc bx jmp short s ok: mov dx,bx mov ax ,4c00h int 21h code ends end start 检测点9.3 补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。 assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s:mov cl,[bx] mov ch,0 inc cx inc bx loop s ok:dec bx mov dx,bx mov ax,4c00h int 21h code ends end start 书P101,执行loop s时,首先要将(cx)减1。 “loop 标号”相当于 dec cx if((cx)≠0) jmp short 标号 检测点10.1 补全程序,实现从内存1000:0000处开始执行指令。 assume cs:code stack segment db 16 dup (0) stack ends code segment start: mov ax,stack mov ss,ax mov sp,16 mov ax, 1000h

《汇编语言》学习笔记(清华大学 王爽)

清华大学《汇编语言》(王爽)读书笔记 第一章基础知识 ◎汇编语言由3类指令组成 汇编指令:机器码的助记符,有对应机器码。 伪指令:没有对应机器码,由编译器执行,计算机并不执行 其他符号:如+-*/,由编译器识别,没有对应机器码 ◎一个CPU有n根地址线,则可以所这个CPU的地址线宽度为n,这样的CPU最多可以寻找2的n 次方个内存单元。 ◎ 1K=2^10B 1M=2^20B 1G=2^30B ◎8086 CPU地址总线宽度为20,寻址范围为00000~FFFFF 00000~9FFFF 主存储器地址空间(RAM) A0000~BFFFF 显存地址空间 C0000~FFFFF 各类ROM地址空间 第二章寄存器(CPU工作原理) ◎16位结构描述了一个CPU具有下面几个方面的结构特性 运算器一次最多可以处理16位的数据 寄存器的最大宽度为16位 寄存器和运算器之间的通路为16位 ◎8086有20位地址总线,可以传送20位地址,达到1M的寻址能力。采用在内部用两个16位地址合成的方法来形成一个20位的物理地址 ◎物理地址 = 段地址 × 16 + 偏移地址 ◎在编程是可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址位16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB ◎8086有四个段寄存器 CS、DS、SS、ES ◎CS为代码段寄存器,IP为指令指针寄存器。任意时刻,设CS中内容为M、IP中内容为N,8086CPU从内存M×16+N读取一条指令执行 ◎不能用mov修改CS、IP,因为8086CPU没有提供这样功能,可用指令JMP 段地址:偏移地址。JMP 2AE3:3 JMP AX 修改IP 第三章寄存器(内存访问) ◎DS数据段寄存器。不能将数据直接送入段寄存器,所以『MOV DS, 1』不正确 ◎字在存储时要两个连续的内存单元,低位在低地址,高位在高地址 ◎[address]表示一个偏移地址为address的内存单元 ◎SS:SP指向栈顶元素 ◎PUSH AX:(1)SP = SP - 2;(2)AX送入SS:SP ◎POP AX:(1)SS:SP送入AX;(2)SP = SP + 2 ◎PUSH/POP 寄存器 PUSH/POP 段寄存器 PUSH/POP 内存单元 第四章第1个程序 ◎可执行文件包含两部分:程序和数据,相关的描述信息 ◎程序加载后, ds中存放这程序所在内存区的段地址,这个内存区的偏移地址为0,策程序所在的内存区的地址为ds:0;这个内存区的前256个字节中存放的是PSP,dos用来和程序进行通信。从256字节处向后的空间存放的是程序。 第五章 [BX]和loop指令 ◎[BX]表示一个内存单元,它的段地址在ds中,偏移地址在bx中。MOV AX,[BX] MOV AL,[BX]

汇编语言王爽检测点答案

汇编语言王爽检测点答案 第一章.检测点1.1 (1) 13 (2) 1024,0,1023 (3) 8192,1024 (4) 2^30,2^20,2^10 (5) 64,1,16,4 (6) 1,1,2,2,4 (7) 512,256 (8) 二进制 注:符号'^'指求幂运算(如: 2^30指2的30次方) 第二章 检测点2.1 (1)大家做这题的时候一定要注意,要看清楚数制,比如是二进制还是十进制,还是十六进,我当时没注意,做错了!!呵呵!! 第一空:F4A3H 第二空:31A3H 第三空:3123H 第四空:6246H 第五空:826CH 第六空:6246H 第七空:826CH 第八空:04D8H 第九空:0482H 第十空:6C82H 第十一空:D882H 第十二空:D888H 第十三空:D810H 第十四空:6246H (2) mov ax,2 add ax,ax add ax,ax add ax,ax

检测点2.2 (1)00010H 1000fH (2)0001H 2000H 检测点2.3 共修改了4次ip 第一次mov ax,bx 第二次是sub ax,ax 第三次是jmp ax 第四次是执行 jmp ax 最后ip的值是0 因为ax的值是零!! 检测点3.1 (1) 第一空:2662H 第二空:E626H 第三空:E626H 第四空:2662H 第五空:D6E6H 第六空:FD48H 第七空:2C14H 第八空:0000H 第九空:00E6H 第十空:0000H 第十一空:0026H 第十二空:000CH 注意:ax中存取的是字型数据,高地址存放高字节,低地址存放低字节!!(一定要小心)

汇编语言第二版王爽完整答案

薈芃莃肆蒀膁蚃第1章基础知识 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为13。 (2)1KB的存储器有1024个存储单元。存储单元的编号从0到1023。 (3)1KB的存储器可以存储1024*8个bit,1024个Byte。 (4)1GB、1MB、1KB分别是2^30、2^20、2^10 Byte。(n^m的意思是n的m次幂) (5)8080、8088、80286、80386的地址总线宽度分别是16根、20根、24根、32根,则它们的寻址能力分别为:64(KB)、1(MB)、16(MB)、4(GB)。 (6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为:1(B)、1(B)、2(B)、2(B)、4(B)。 (7)从内存中读取1024字节的数据,8086至少要读512次、80386至少要读256次。 (8)在存储器中,数据和程序以二进制形式存放。 莅羈膇膃蚅莅聿第2章寄存器答案 检测点2.1 (1) 写出每条汇编指令执行后相关寄存器中的值。 mov ax,62627 AX=F4A3H mov ah,31H AX=31A3H mov al,23H AX=3123H add ax,ax AX=6246H mov bx,826CH BX=826CH mov cx,ax CX=6246H mov ax,bx AX=826CH add ax,bx AX=04D8H mov al,bh AX=0482H mov ah,bl AX=6C82H add ah,ah AX=D882H add al,6 AX=D888H add al,al AX=D810H mov ax,cx AX=6246H (2) 只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。 解: mov ax,2 add ax,ax add ax,ax add ax,ax 检测点2.2 (1) 给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为00010H到1000FH。 (2) 有一数据存放在内存 20000H 单元中,先给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:最小为1001H,最大为2000H。 检测点2.3

汇编语言(王爽)第三版检测点答案(带目录).pdf

汇编语言答案(王爽) 第一章 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为13位。 (2)1KB的存储器有1024个存储单元,存储单元的编号从0到1023。(3)1KB的存储器可以存储8192(2^13)个bit,1024个Byte。 (4)1GB是1073741824(2^30)个Byte、1MB是1048576(2^20)个Byte、1KB是1024(2^10)个Byte。 (5)8080、8088、80296、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为:64(KB)、1(MB)、16(MB)、4(GB)。(6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为:1(B)、1(B)、2(B)、2(B)、4(B)。 (7)从内存中读取1024字节的数据,8086至少要读512次,80386至少要读256次。 (8)在存储器中,数据和程序以二进制形式存放。 解题过程: (1)1KB=1024B,8KB=1024B*8=2^N,N=13。 (2)存储器的容量是以字节为最小单位来计算的,1KB=1024B。 (3)8Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。 (4)1GB=1073741824B(即2^30)1MB=1048576B(即2^20)1KB=1024B(即2^10)。(5)一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(一个内存单元=1Byte)。 (6)8根数据总线一次可以传送8位二进制数据(即一个字节)。 (7)8086的数据总线宽度为16根(即一次传送的数据为2B)1024B/2B=512,同理1024B/4B=256。 (8)在存储器中指令和数据没有任何区别,都是二进制信息。 第二章 检测点 2.1 (1)写出每条汇编指令执行后相关寄存器中的值。 mov ax,62627AX=F4A3H mov ah,31H AX=31A3H mov al,23H AX=3123H

汇编语言王爽课后答案

汇编语言王爽课后答案 【篇一:汇编语言课后习题答案王爽主编】 一个值为0的字节,找到后,将它的偏移地址存储在dx中。 assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0s: mov ch,0 mov cl,[bx] jcxz ok;当cx=0时,cs:ip指向okinc bx jmp short s ok: mov dx,bx mov ax ,4c00h int 21h code ends end start 检测点9.3 补全编程,利用loop指令,实现在内存2000h段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。 assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s:mov cl,[bx] mov ch,0 inc cx inc bx loop s ok:dec bx mov dx,bx mov ax,4c00h int 21h code ends end start 书p101,执行loop s时,首先要将(cx)减1。 “loop 标号”相当于 dec cx if((cx)≠0) jmp short 标号

检测点10.1 补全程序,实现从内存1000:0000处开始执行指令。 assume cs:code stack segment db 16 dup (0) stack ends code segment start: mov ax,stack mov ss,ax mov sp,16 mov ax, 1000h mov ax,0 push ax retf code ends end start 执行reft指令时,相当于进行: pop ip pop cs 根据栈先进后出原则,应先将段地址cs入栈,再将偏移地址ip入栈。 检测点10.3 下面的程序执行后,ax中的数值为多少? 内存地址机器码汇编指令执行后情况 1000:0 b8 00 00 mov ax,0 ax=0,ip指向1000:3 1000:3 9a 09 00 00 10 call far ptr s pop cs,pop ip,ip指向1000:9 1000:8 40 inc ax 1000:9 58 s:pop ax ax=8h add ax,ax ax=10h pop bx bx=1000h add ax,bx ax=1010h 用debug进行跟踪确认,“call far ptr s”是先将该指令后的第一个字节段地址cs=1000h入栈,再将偏移地址ip=8h入栈,最后转到标号处执行指令。 出栈时,根据栈先进后出的原则,先出的为ip=8h,后出的为cs=1000h 检测点10.4

汇编语言(王爽)第二版答案

汇编语言第二版答案-王爽 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位。 (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 。 (3)1KB的存储器可以存储 8192(2^13)个bit, 1024个Byte。 (4)1GB是 1073741824 (2^30)个Byte、1MB是 1048576(2^20)个Byte、1KB是 1024(2^10)个Byte。 (5)8080、8088、80296、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为: 64 (KB)、 1 (MB)、 16 (MB)、 4 (GB)。 (6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为: 1 (B)、 1 (B)、 2 (B)、 2 (B)、 4 (B)。 (7)从存中读取1024字节的数据,8086至少要读 512 次,80386至少要读 256 次。 (8)在存储器中,数据和程序以二进制形式存放。 解题过程: (1)1KB=1024B,8KB=1024B*8=2^N,N=13。 (2)存储器的容量是以字节为最小单位来计算的,1KB=1024B。 (3)8Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。 (4)1GB=1073741824B(即2^30)1MB=1048576B(即2^20)1KB=1024B(即2^10)。 (5)一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个存单元。(一个存单元=1Byte)。 (6)8根数据总线一次可以传送8位二进制数据(即一个字节)。 (7)8086的数据总线宽度为16根(即一次传送的数据为2B)1024B/2B=512,同理 1024B/4B=256。 (8)在存储器中指令和数据没有任何区别,都是二进制信息。 检测点 2.1

王爽汇编语言课程设计一原创

课程设计,整体思路是通过子程序调用来实现完成整个设计过程 用SI来寻址数据段,DI来寻址屏幕显示的内存空间。要hold住,不怕麻烦,才可以如有疑惑,欢迎交流zych_09@https://www.wendangku.net/doc/3d6095797.html, assume cs:code data segment db '1975','1976','1977','1978','1979','1980','1981','1982','1983' db '1984','1985','1986','1987','1988','1989','1990','1991','1992' db '1993','1994','1995' dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 dw 11542,14430,15257,17800 data ends table segment db 21 dup ('year summ ne ?? ') table ends code segment begin: mov ax,data mov ds,ax mov bx,0 mov si,0 mov di,0 mov ax,table mov es,ax mov ax,0 mov cx,21 s: push cx push di mov cx,4 s1: mov al,[di] mov es:[bx+si],al inc si inc di loop s1 pop di push di inc si mov cx,4

汇编语言(王爽)Word版(1)

汇编语言(王爽)Word版(1) 第1章基础知识 汇编语言是直接在硬件之上工作的编程语言,我们首先要了解硬件系统的结构,才能 有效地应用汇编语言对其编程。在本章中,我们对硬件系统结构的问题进行一部分的探 讨,以使后续的课程可在一个好的基础上进行。当课程进行到需要补充新的基础知识(关 于编程结构或其他的)的时候,再对相关的基础知识进行介绍和探讨。我们的原则是,以 后用到的知识,以后再说。 在汇编课程中我们不对硬件系统进行全面和深入的研究,这不在课程的范围之内。关 于PC机及CPU物理结构和编程结构的全面研究,在《微机原理与接口》中进行;对于 计算机一般的结构、功能、性能的研究在一门称为《组成原理》的理论层次更高的课程中 进行。汇编课程的研究重点放在如何利用硬件系统的编程结构和指令集有效灵活地控制系 统进行工作。 1.1 机器语言 说到汇编语言的产生,首先要讲一下机器语言。机器语言是机器指令的集合。机器指

令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数 字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。 上面所说的计算机指的是可以执行机器指令,进行运算的机器。这是早期计算机的概 念。现在,在我们常用的PC机中,有一个芯片来完成上面所说的计算机的功能。这个芯 片就是我们常说的CPU(Central Processing Unit,中央处理单元),CPU是一种微处理器。以后我们提到的计算机是指由CPU和其他受CPU直接或间接控制的芯片、器件、设备组 成的计算机系统,比如我们最常见的PC机。 每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控 制,使它工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。 早期的程序设计均使用机器语言。程序员们将用0、1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。 应用8086CPU完成运算s=768+12288-1280,机器码如下。 101100000000000000000011 000001010000000000110000 001011010000000000000101 假如将程序错写成以下这样,请你找出错误。

汇编语言王爽第二版课后答案

第一章基础知识 检测点(第8页) ---------------------- (1) 13 (2) 1024,0,1023 (3) 8192,1024 (4) 2^30,2^20,2^10 (5) 64,1,16,4 (6) 1,1,2,2,4 (7) 512,256 (8) 二进制 注意: 1.第4题中的符号'^'指求幂运算(如: 2^30指2的30次方) 第二章寄存器(CPU工作原理) 检测点(第18页) ---------------------- (1)写出每条汇编指令执行后相关寄存器中的值。第一空:F4A3H 第二空:31A3H 第三空:3123H 第四空:6246H 第五空:826CH 第六空:6246H 第七空:826CH 第八空:04D8H 第九空:0482H 第十空:6C82H 第十一空:D882H 第十二空:D888H 第十三空:D810H 第十四空:6246H (2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。 解答如下: mov ax,2 add ax,ax add ax,ax add ax,ax 检测点(第23页) ---------------------- (1)00010H,1000FH (2)1001H,2000H 第2题说明: 因为段的起始地址要为16的倍数。所以当段地址小于1001H或大于2000H时CPU都无法寻到。 检测点(第33页) ---------------------- 答:CPU修改了4次IP的值。 情况如下: 第1次:执行完mov ax,bx后 第2次:执行完sub ax,ax后 第3次:读入jmp ax后 第4次:执行完jmp ax后 最后IP的值为0 实验1 查看CPU和内存,用机器指令和汇编指令编程(第33页)

相关文档
相关文档 最新文档