zoukankan      html  css  js  c++  java
  • 汇编语言实验五

    • 实验任务一

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

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

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

    (3)先执行到000D之前,看看ds是否已成功指向数据段

    (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

    • 实验任务二

     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/16+1)*16(即数据的分配是以16个字节为单位的)

    name segment
    :
    name ends
    • 实验任务三

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

    (1)同样用r查看各个寄存器的值,并用u精确反汇编

    (2)用g命令执行至000D之前,看看ds是否指向数据段data

    (3)从上图可以看出,ds指向了数据段data,接着执行到程序返回前,再查看数据段data的值

    (4)从上图可以看到,数据段中的值没有变化

    2.书上问题的解答:

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

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

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

    • 实验任务四

    1.以实验任务三为例,删除end后面的start,执行看结果,步骤与上面一致

    (通过上面的截图,我们可以发现与任务三中的结果完全一致,也就是说,除去了end后面的start,程序仍然能正确执行)

    2.再以任务二为例,删去end后面的start,再执行查看结果,步骤与上面一致

    (上图注意:此时精确反汇编的不同,变成以cs为段地址,以20h为偏移地址

    (虽然执行的过程有所差异,但是执行后的结果是一致的,即去掉了end后面的start,也能正确执行)

    3.书上问题解答:

     (1)比较上面的过程与结果,我认为这三个程序去掉了end后面的start都能正确执行。唯一的不同点在于,虽然去掉了start,cs:ip的值会指向程序起始位置的段地址,但实际上随着程序的执行,最后总会将代码段执行完;而加上start之后,cs:ip的值一开始就直接指向了我们的代码段,更方便我们的操作。

    • 实验任务五

     1.填写的程序代码如下:

    start:   mov ax,a
             mov ss,ax ;利用段寄存器ss指向a段的起始位置
    
             mov ax,b
             mov es,ax ;利用段寄存器es指向b段的起始位置
    
             mov ax,c
             mov ds,ax ;利用段寄存器ds指向c段的起始位置
    
             mov bx,0
             mov cx,8
        s:   mov al,ss:[bx]
             mov [bx],al  ;将a段数据复制到c段中
             mov al,es:[bx]
             add [bx],al  ;将b段数据与c段的数据相加,结果保存在c段中
             inc bx       ;由于定义的是字节数据,所以只需要将bx加一
             loop s
    
             mov ax,4c00h
             int 21h

    2.利用debug跟踪、执行

    (1)先用r查看各个寄存器的值,再用u反汇编

    (2)先执行到000A之前,可以查看a段和b段的数据,a段由ss段寄存器指向,b段由es段寄存器指向

    (3)再执行到0022之前,看看c段中的结果

    (4)从上图可以看到,实现了将a段和b段中数据的依次相加

    3.补充:做完该实验才看到老师的tips,于是决定按照分段利用es的方法,再完成一次

    (1)代码如下:

    start: mov ax,c
             mov ds,ax ;利用段寄存器ds指向c段起始地址
             mov ax,a
             mov es,ax ;先利用段寄存器es指向a段起始地址
    
             mov bx,0
             mov cx,8
       s:   mov al,es:[bx] 
             mov [bx],al     ;做一个将a段数据复制到c段中的循环
             inc bx
             loop s
    
             mov ax,b
             mov es,ax  ;再利用段寄存器es指向b段起始地址
    
             mov bx,0
             mov cx,8
       s0:  mov al,es:[bx]
             add [bx],al       ;再做一个将b段数据加到c段中的循环
             inc bx
             loop s0
    
             mov ax,4c00h
             int 21h

    (2)利用debug跟踪、执行

    (先执行到000A之前,看看a段的数据)

    (再执行到0018之前,看看c段的数据)

    (接着执行到001D之前,查看b段的数据)

    (最后执行到程序返回前,看看c段中的结果)

    (从上图可以看到,实现了a、b段数据的依次相加

    • 实验任务六

     1.填写的代码如下:

    start: mov ax,a
             mov ds,ax ;利用段寄存器ds指向a段
    
             mov ax,b
             mov ss,ax   ;利用段寄存器ss指向b段,让b段作为栈空间
             mov sp,16  ;初始化栈顶
    
             mov bx,0
             mov cx,8
         s:  push [bx]
             add bx,2
             loop s
    
             mov ax,4c00h
             int 21h

    2.利用debug跟踪、执行

    (1)用r查看各个寄存器的值,再用u反汇编

    (2)先执行到0005,查看a段数据

    (3)最后执行到程序返回前,看看b段中的数据

    (从上图可以看到,实现了将a段中的前8个字型数据逆序存储到b段中

    • 总结与体会

    1.通过本次实验熟悉并掌握了编写、调试具有多个段的程序,收获非常大

    2.我上网搜索了一下关于实验任务二中提到的 “段中数据大小与实际占用空间” 这部分的内容:

    3.关于实验任务一、二、三中都提到的,code段、data段、stack段的段地址的关系:

        对于任务一和二,data段定义用了16个字节(0~f),stack段定义用了16个字节(10~2f),所以段地址会与代码段相差2和1;而在任务三中,代码段占了32个字节,所以后面定义的data的段地址和stack的段地址会与代码段相差3和4。

    4.关于实验任务五,在我一开始写的代码中,除了ds和es之外,我还运用了ss段寄存器,这样就只需要执行一次循环,最后也同样达到了目的。因为我觉得当ss不用来定义栈空间时,它就只是一个普通的段寄存器,所以一样可以派上用场。

  • 相关阅读:
    hdu4578线段树维护平方和,立方和(加,乘,赋值)或者珂朵莉树
    珂朵莉树(ODT老司机树)
    Codeforces Round #524 (Div. 2)D
    HDU1402 FFT高精度乘法模板题
    中国剩余定理poj1006
    POJ
    Install and Config MySQL 8 on Ubuntu
    Protobuf Examples
    Learning Thrift
    Flask Quickstart
  • 原文地址:https://www.cnblogs.com/kwcymino/p/10006595.html
Copyright © 2011-2022 走看看