实验4 —— [bx]和loop的使用

实验

  1. 综合使用 loop[bx],编写完整汇编程序,实现向内存 b800:07b8 开始的连续 16 个字单元重复填充字数据 0403H
  • 以下为示例程序:

    assume cs:code                    # 1
    code segment                      # 2
          mov ax, 0b800h              # 3     ; 数据必须以数字开头,要在字母前补 0
          mov ds, ax                  # 4
          mov cx, 16                  # 5     ; 设置循环次数为 16
          mov bx, 07b8h               # 6     
                                      # 7
    S:    mov [bx], word ptr 0403h    # 8     ; 将字数据 0403h 送向偏移地址
          inc bx                      # 9     ; 字数据占 2 个内存单元 bx 自增两次
          inc bx                      # 10
          loop s                      # 11
                                      # 12
          mov ax, 4c00h               # 13
          int 21h                     # 14
    code ends                         # 15
    end                               # 16   
  • 编译、连接和运行结果如下图所示:

    ex4_1@3x.png

  • 将源代码程序中字数据 0403H 修改为 0441H,再次运行的结果如下:

    ex4_10@3x.png

    结论与实验 3 是一致的,b8000 开始的一块内存与显示有关,且修改的字数据的前两位和颜色有关,后两位是字符的 ASCII 码值。

  1. 综合使用 loop[bx],编写完整汇编源程序,实现向内存 0:2000:23F 依次传送数据 063(3FH)
  • 使用 loop[bx]mov实现

    • 以下为示例程序:
    assume cs:code                    # 1
    code segment                      # 2
              mov ax, 0020h           # 3
              mov ds, ax              # 4
              mov cx, 64              # 5     ; 设置循环次数为 64
              mov bx, 0               # 6
                                      # 7
    S:        mov [bx], bl            # 8     ; 将字节数据送向偏移地址
              inc bx                  # 10    
              loop s                  # 11
                                      # 12
          mov ax, 4c00h               # 13
          int 21h                     # 14
    code ends                         # 15
    end                               # 16
    • 编译、连接如下图所示:

    ex4_2@3x.png

    • g 命令执行程序,并用 d 命令显示内存中的内容,如下图所示:

    ex4_3@3x.png

    结果很明显。还有,这里因为数据不大于 255 所以传送字节数据。

  • 还可以利用栈的特性,使用 looppush 实现

    • 以下为示例程序:
    assume cs:code                    # 1
    code segment                      # 2
          mov ax, 0020h               # 3
          mov ss, ax                  # 4     ; 根据之前的实验得,在修改 ss 时一并执行
          mov sp, 0040h               # 5     ; 下一条指令,下一条指令一般是修改 sp 的值
          mov bx, 3f3eh               # 6     ; 由于栈是对字数据操作,不得不将 2 个内存
                                      # 7     ; 单元的值一起写入 16 位寄存器
          mov cx, 32                  # 8     ; 对字数据操作,循环 32 次
                                      # 9
    s:        push bx                 # 10    ; 压栈时栈顶指针上移 2 个单位 (sp - 2)
          sub bl, 2                   # 11
          sub bh, 2                   # 12
          loop s                      # 13
                                      # 14
          mov ax, 4c00h               # 15
          int 21h                     # 16
    code ends                         # 17
    end                               # 18
    • 编译、连接如下图所示:

    ex4_4@3x.png

    • 重复上次实验的操作,如下图所示:

    ex4_5@3x.png

    根据压栈的特性,需要先压入高地址单元的内存,所以是按从 3f0 的顺序压入。

  1. 下面的程序的功能是将 mov ax, 4c00h 之前的指令复制到内存 0:200 处,补全程序并调试。
assume cs:code                      # 1
code segment                        # 2
        mov ax, __                  # 3
        mov ds, ax                  # 4
        mov ax, 0020h               # 5
        mov es, ax                  # 6
        mov bx, 0                   # 7
        mov cx, __                  # 8
                                    # 9
s:      mov al, [bx]                # 10
        mov es:[bx], al             # 11
        inc bx                      # 12
        loop s                      # 13
                                    # 14
        mov ax, 4c00h               # 15
        int 21h                     # 16
code ends                           # 17
end                                 # 18

指令执行是因为 cs:ip 指向了它,cs 就是指令的段地址,我们只需要把指令的段地址交给数据段就能直接通过 [bx] 来获取内存中的内容了。所以 # 3 行的空格填 cs

由于不确定指令占用多少字节,现在将 cx 的值设为 0 并编译、连接,如下图所示:

ex4_6@3x.png

使用 debug 中的 u 命令反汇编,查看指令占用了多少内存,如下图所示:

ex4_7@3x.png

可见 mov ax, 4c00h 之前的命令占用 1e87:00001e87:001517h 个字节。

由此可得,共循环 17h 次,因此 # 8 行的空格填 17h,并将 cx 的值设置为 17h,重新编译、连接和反汇编,如下图所示:

ex4_8@3x.png

确认无误后,使用 g 命令运行,并使用 d 命令查看结果,如下图所示:

ex4_9@3x.png

可见已成功将 mov ax, 4c00h 之前的指令复制到指定内存。

尾巴

这次没有什么好说的,那就简单说一下在实验时可能遇到的问题:

  • debug 中的 mov ax, [0] 与程序中的 mov ax, [0] 是不同的,程序中的会被编译器当作 mov ax, 0, 解决方法有两种 mov bx, 0 mov ax, [bx] 或者是 mov ax, ds:[0]
  • 程序中所有数据不能以字母开头,如果是字母开头的 16 进制数,需要在前面补 0。
  • 栈只能对字数据进行操作,有时需要对操作数据做一些转换。

转载于:https://www.cnblogs.com/jordangong/p/9977839.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值