汇编 书上实验

实验五   看看大佬的地方:https://www.cnblogs.com/kwcymino/p/10006595.html

 利用doxbox

1.利用debug加载、跟踪程序

(1)先利用r命令来查看各个寄存器的值

(2)从cx中可知道程序的长度,用cx中的值减去20h(数据段和栈段已分配的空间)得到代码段的长度,用u命令精确反汇编

(3)先执行到000D之前,看看ds是否已成功指向数据段   -g:直接执行程序

(4)从上图可以看到ds已指向数据段,然后我们接着执行到程序返回前,即到001D之前,再查看一次数据段的内容

(5)从上图可以看到,数据段没有发生变化

2.书上的问题解答:

(1)程序返回前,data段中的数据为 23 01 56 04 89 07 BC 0A-EF 0D ED 0F BA 0C 87 09

(2)程序返回前,CS=076C,SS=076B,DS=076A

(3)设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1

-----也可以一直利用-t指令执行完程序。再利用-r查看状态

 -----如果直接-g的话 出来的是  再利用-r查看状态反倒回到最开始的状态了

第二题: 

1.利用debug加载、跟踪程序

(1)先利用r命令查看各个寄存器的值

(2)从上图的cx我们可以看到,cx的值与任务一的一样虽然任务二只定义了两个字数据的数据段和两个字型数据当栈空间,但实际上在内存分配上还是给它们16个字节的空间,于是我用u命令精确反汇编一下

(3)再用g命令执行到000D以前,看看ds是否指向数据段data

(4)从上图看出ds已指向数据段data,再执行到程序返回前,看看数据段data的变化

(5)从上图看出,数据段没有变化

2.书上问题的解答:

(1)程序返回前,data段中的数据为 23 01 56 04

(2)程序返回前,CS=076C,SS=076B,DS=076A

(3)设程序加载后,code段的段地址为X,则code段的段地址为X-2,stack段的段地址为X-1

(4)对于如下定义的段,若段中的数据占N个字节,则程序加载后,该段实际占有的空间为((N+15)/16)*16(即数据的分配是以16个字节为单位的)

name segment
:
name ends

对于第四问的讲解:

因为每个段都是以16字节来对齐的,但是最大不能超过64KB 。这也就是说,如果你的段数据在16字节内,一样会被当做一个字节段来算,就是16字节。 要是大于16字节呢,那么如果多出就算是1个字节,因为已经超过一个16字节,多出来的1个字节 也得有一个字节段的容量来存储它,所以这时得占两个字节段,就是32字节,以此类推! 

---

组合后的实际地址=段寄存器内容×16+偏移量寄存器内容,从这个公式可以看到,每一个段的地址都对齐在16的倍数上。

/  这个符号是取整 

N分为被16整除和不被16整除。  
当N被16整除时: 占有的空间为(N/16)*16  
当N不被16整除时: 占有的空间为(N/16+1)*16,N/16得出的是可以整除的部分,还有一个余数,余数肯定小于16,加上一个16。 
两种情况总结成一个通用的公式:((N+15)/16)*16

解释了为啥:任务二cx的值与任务一的一样,明明定义少了。

 第三题   看链接即可

2.书上问题的解答:

(1)程序返回前,data段中的数据为 23 01 56 04

(2)程序返回前,CS=076A,SS=076E,DS=076D

(3)设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4

第四题??

第五题:

     我主要麻烦在不会-u-g的使用 只能-t

 第六题

  

实验四

(1)编程,向内存0:200~0:23f依次传送数据0~63.

assume cs:code
code segment
  mov ax,0020h
  mov ds,ax
  mov bx,0

  mov cx,64
s:mov [bx],bx ;[bx]是省略后的物理地址 而后面就是个立即数
  inc bx
  loop s

 mov ax,4c00h
 int 21h
code ends
end

2. 向内存0:200H~0:23fH依次传送数据0~63(3FH),9条命令的程序的简化版本(不包括伪代码)

(3)程序功能是将"mov ax,4c00h"之前的指令复制到内存0:200处,补全程序:

 关于这两个地方的解释

1. https://www.cnblogs.com/kwcymino/p/9960424.html

2. mov ax,4c00h这个的地址:指令是存放在CS段内(此处写为CODE也是对的,因为都指向一个区域)/ 这应该存放的是该程序的段地址

3.debug查看程序代码总长度

;只写关键代码
;每次复制单字节数据,并通过al中转
;程序入口为cs:0(ip=0),所以第一空处传递段地址为cs
;接下来需要确定循环次数,即mov ax,4c00h之前的代码长度
;而程序总代码长度可通过debug加载后通过u命令看出
;先将第二空位随便设为1,加载后观察mov ax,4c00h之前代码为0000~0016h,总长度为23.

使用debug调试一个EXE文件时候,使用r命令查看寄存器状态,其中cx寄存器的值(初始值)就是该程序代码的大小(按照字节数)。我们可以通过运行debug程序来调试生成的EXE文件,前提你先将CX寄存器赋个值。侧面验证CX寄存器的另一个作用。

根据cx寄存器,可知cx为1cH,因为在载入程序时,cx保存程序的长度,减去5是为减去mov ax,4c00h和int 21h的长度。所以,001cH-0005H=23 个

所以 cx 寄存器赋值为 17H。

实验八 

分析程序,在运行前思考:这个程序是否能够正确返回?
运行之后再思考:为什么是这种结果?
通过这个程序加深对相关内容的理解。

assueme cs:codesg
codesg segment
        mov ax,4c00h
        int 21h
start:  mov ax,0
    s:  nop
        nop

        mov di,offset s
        mov si,offset s2
        mov ax,cs:[si]
        mov cs:[di],ax

    s0: jmp short s

    s1: mov ax,0
        int 21h
        mov ax,0

    s2: jmp short s1
        nop
codesg ends
end start

CPU在执行jmp短指令的时候并不需要转移的目的地址,而包含的是转移的位移。这个位移,是编译器根据汇编指令中的“标号”计算出来的。

实验10

https://blog.csdn.net/XHS_12302/article/details/52056350 

1.  显示字符串

assume cs:code
   data segment
   db 'Welcome to masm!',0
   data ends

 code segment
   start:  mov dh,8
           mov dl,3
           mov cl,2
           mov ax,data
           mov ds,ax
           mov si,0
          call show_str
         mov ax,4c00h
         int 21h
   show_str: push dx
             push cx
             push ds
             push si

     mov ax,0b800h
     mov es,ax
     
     mov al,160
     mul dh
     mov bx,ax
     mov al,2
     mul dl
     add bx,ax
    mov al,cl
    
         s: mov cl,[si] 
             jcxz ok
                mov dx,[si]
              mov es:[bx],dx
              mov es:[bx+1],al
              inc si
              add bx,2
              loop s

 ok:             
  pop si
  pop ds
  pop cx
  pop dx
ret
code ends
end start 

2.  解决除法溢出的问题

assume cs:code
    code segment
    start:mov ax,4240h
          mov dx,000fh
          mov cx,0Ah
          call divdw
          mov ax,4c00H
          int 21h
divdw:
      push ax
      mov ax,dx
      mov dx,0
      div cx
      mov bx,ax
      pop ax
      div cx
      mov cx,dx
      mov dx,bx
      ret    
    code ends
end start

3.数值显示

assume cs:code
  data segment
   db 16 dup(0)
  data ends

 
  code segment
    start:mov ax,12666
          mov bx,data
          mov ds,bx
          mov si,0
          call dtoc
          mov dh,8
          mov dl,3
          mov cl,2
          call show_str
          mov ax,4c00h
          int 21h
dtoc:
        mov cx,ax    ;17
       jcxz bk
         push ax
       mov al,ah
       mov ah,0
       mov bl,10
       div bl
     mov cl,al
     mov ch,ah
       pop ax
     mov ah,ch
       div bl
     mov dl,ah
     mov dh,0
      push dx
       mov ah,cl
     jmp short dtoc   ;29
     bk:pop ax 
        add ax,30h
        mov [si],al
        
        pop ax 
        add ax,30h
        mov [si+1],al
       
        pop ax 
        add ax,30h
        mov [si+2],al
        
        pop ax 
        add ax,30h
        mov [si+3],al    ;44
        
        pop ax 
        add ax,30h
        mov [si+4],al
        mov byte ptr [si+5],0
        ret
       
     
show_str:
            mov si,0

     mov ax,0b800h
     mov es,ax
     
     mov al,160
     mul dh
     mov bx,ax
     mov al,2
     mul dl
     add bx,ax
    mov al,cl
    
         s: mov cl,[si] 
             jcxz ok
                mov dx,[si]
              mov es:[bx],dx
              mov es:[bx+1],al
              inc si
              add bx,2
              loop s

 ok: ret    
  code ends
end start

 实验七

  

si di 相当于指针

Nop指令是空指令 什么都不干 占存储空间 1个nop占一字节

原文地址:https://www.cnblogs.com/yundong333/p/12859635.html