汇编语言(王爽 第三版)检测点和实验

第一章
检测点1.1

  1. 13
      (8kb = 8 * 1024 = 2^13)

  2. 1024 0 1023

  3. 8*1024 1024
      (1 byte = 8 bit,计算机以byte为存储单位)

  4. 1024^3 1024^2 1024

  5. 2^6 1 2^4 2^2
      (kb = 2^10 Mb = 2^20 Gb = 2^30)

  6. 1 1 2 2 4

  7. 512 256
      (8086的寄存器为16位寄存器,一次可以读取两个字节,80386为32位寄存器)

  8. 二进制

第二章
检测点2.1
1)
AX = F4A3h
AX = 31A3h
AX = 3123h
AX = 6246h
BX = 826Ch
CX = 6246h
AX = 826Ch
AX = 04D8h
AX = 0482h
AX = 6C82h
AX = D882h
AX = D888h
AX = D810h
AX = 6246h

mov ax,2
add ax,ax
add ax,ax
add ax,ax

检测点2.2
1)00010h 1000fh
(0001h+0000h 0001h+ffffh)

2)1001h 2000h
(偏移地址的范围为0000-ffff,内存单元=段地址*16+偏移地址,当偏移地址最小时,段地址最大,偏移地址最大时,段地址最小)

检测点2.3
4次修改IP,最后IP为0

第三章
检测点3.1
1)
mov ax,1
mov ds,ax
mov ax,[1000] AX = 2662h
mov bx,[1001] BX = E626h
mov ax,bx AX = E626h
mov ax,[0000] AX = 2662h
mov bx,[0002] BX = D6E6h
add ax,bx AX = FD48h
add ax,[0004] AX = 2C14h
mov ax,0 AX = 0000h
mov al,[0002] AX = 00E6h
mov bx,0 BX = 0000h
mov bl,[000C] BX = 0026h
add al,bl AX = 000Ch

CS = 2000h,IP = 0,DS = 1000h
mov ax,6622h AX = 6622h
jmp 0ff0:0100h CS = 0ff0 IP = 0100h
mov ax,2000h AX = 2000h
mov ds,ax DS = 2000h
mov ax,[0008] AX = C389h
mov ax,[0002] AX = EA66h
mov ax,6622h AX = 6622h
数据和程序表达上没有区别,只跟存储的地方有关,存在数据段中即为数据,存在程序段中就是程序

检测点3.2
1)
mov ax,2000h
mov ss,ax
mov sp,10h

mov ax,1000h
mov ss,ax
mov sp,0

实验三:

assume cs:cdsg
    
cdsg segment
    mov ax,2000H
	mov ss,ax
	mov sp,0
	add sp,10
	pop ax
	pop bx
    push ax
	push bx
	pop ax
	pop bx

	mov ax, 4c00H
	int 21H

cdsg ends

end

实验四:

assume cs:code
code segment
   mov ax,cs
   mov ds,ax
   mov ax,0020h
   mov es,ax
   mov bx,0
   mov cx,17h
  s:mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s
    mov ax,4c00h
    int 21h
code ends
end

(1)复制的是什么?从哪里到哪里?
复制的是如上代码段数据,从mov ax,cs到loop s
(2)复制的是什么?有多少个字节?你如何指导要复制的字节的数量?
复制的是机器指令对应的机器代码,共23个字节,用debug命令U显示出代码段,用代码段的结束地址减去代码段的起始地址就是代码长度

第六章
检测点6.1
1)
mov cs:[bx],ax

cs
26或1ah
pop cs:[bx]

实验五
(1)

程序一:
assume cs:code,ds:data,ss:stack

data segment
    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
     dw 0,0,0,0,0,0,0,0
stack ends

code segment

start:  mov ax,stack
        mov ss,ax
        mov sp,16
        
        mov ax,data
        mov ds,ax
        
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
        
        mov ax,4c00h
        int 21h
code ends

end start

1,data段中的数据和原始数据一样,没有变化:
在这里插入图片描述
2,cs=076ch、ss=076bh、ds=076ah
3,data 段的段地址为X-2,stack段的段地址为X-1

(2)

程序二:
assume cs:code,ds:data,ss:stack

data segment
	dw 0123h,0456h
data ends
	
stack segment
	dw 0,0
stack ends

code segment

start:  mov ax,stack
		mov ss,ax
		mov sp,16
		
		mov ax,data
		mov ds,ax
		
		push ds:[0]
		push ds:[2]
		pop ds:[2]
		pop ds:[0]
		
		mov ax,4c00h
		int 21h
code ends

end start		

1,data段中的数据和原始数据一样,没有变化:
在这里插入图片描述
2,cs=076ch、ss=076bh、ds=076ah
3,data 段的段地址为X-2,stack段的段地址为X-1
4,如果段中数据位N个字节,程序加载后,该段实际占据空间为:(N/16的取整数+1)*16个字节。 如果N小于16,那么实际占用16个字节(理解这个小问题);如果N大于16,那么实际占用(N/16的取整数+1)*16个字节。其实都是这个公式。
(3)

程序三:
assume cs:code,ds:data,ss:stack

code segment

start:  mov ax,stack
		mov ss,ax
		mov sp,16
		
		mov ax,data
		mov ds,ax
		
		push ds:[0]
		push ds:[2]
		pop ds:[2]
		pop ds:[0]
		
		mov ax,4c00h
		int 21h
code ends


data segment
	dw 0123h,0456h
data ends
	
stack segment
	dw 0,0
stack ends

end start		

1,data段中的数据和原始数据一样,没有变化:
在这里插入图片描述
2,cs=076ah、ss=076Eh、ds=076dh
3,data 段的段地址为X+3,stack段的段地址为X+4
(4)程序三仍能正确运行,因为
如果不指名程序的(code段的)入口,并且使用end替换end start,都能正常运行。但只有(3)题中程序可以正确的执行(因为只有它是在内存中可执行代码在最前面)。

讲解:因为如果不指名入口,程序会从加载进内存的第一个单元起开始执行,前二个题中,定义的是数据,但CPU还是将数据当做指令代码执行了。只不过程序执行时逻辑上是错误了。但真的能执行的。

   如果指明了程序的入口,CPU会直接从入口处开始执行真正的机器码,直到遇到中断指令返回。此种方式能够确保程序逻辑上的正确。因此有必要为程序来指明入口
程序四:
assume cs:code

a segment
	db 1,2,3,4,5,6,7,8
a ends

b segment
	db 1,2,3,4,5,6,7,8
b ends

cz segment
	db 0,0,0,0,0,0,0,0
cz ends

code segment

start:
assume ds:a,es:b	
	mov ax,a
	mov ds,ax
	
	mov ax, b
	mov es,ax
	
	mov cx, 8
	mov bx,0
	mov ah,0
	mov al,0
	s:  add al, ds:[bx]
		add al, es:[bx]
		push ds
		mov ax, cz
		mov ds,ax
		mov [bx],dl
		pop ds
		inc bx
		loop s

	mov ax,4c00h
	int 21h		
code ends

end start	

结果分析:
1)ds段寄存器在程序中可以存储不同的内存段的段地址,并不是唯一存储一个段地址,es也是如此。
2)合理利用系统自动创建的栈空间,利用栈空间来保存暂存的数据。注意压栈和弹栈的顺序,确保操作的是一个数据对象。
3)在遇到多个数据段的情况下,这种方式可以利用一个段寄存器来对多个内存段寻址。
4)在实际工程中,在程序中保存的数据,都是程序的一些必须的初始化的数据,其他的数据都应保存在磁盘文件中,需要时才读入内存中。此例中的a、b、cz段都是其他的数据,在这里就是演示。

程序五:
assume cs:code

a segment
    dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends

b segment
    dw 0,0,0,0,0,0,0,0
b ends

code segment
start:
	mov ax,a
	mov ds, ax
	
	mov ax, b
	mov ss, ax
	mov sp, 16
	
	mov bx,0
	mov cx,8
	s: 	push ds:[bx]
		add bx,2
		loop s
	mov ax,4c00h
	int 21h		
code ends

end start

你可能感兴趣的:(计算机科学,编程,c语言,计算机组成原理,8086CPU,汇编程序)