汇编语言.实验2

2021/11/6 22:12:26

本文主要是介绍汇编语言.实验2,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 实验任务1
    • 任务1-1
    • 任务1-2
    • 任务1-3
    • 任务1-4
    • 任务1-5
      • 问题一
      • 问题二
  • 实验任务2
    • 分析
    • 代码
    • 截图
  • 实验任务3
    • 分析
    • 代码
    • 截图
      • 装入debug并调试
      • 运行前逻辑段
      • 运行后逻辑段
  • 实验任务4
    • 代码
    • 截图
      • 装入debug并调试
      • 运行前逻辑段
      • 运行后逻辑段
  • 实验任务5
    • 代码
    • 运行结果
    • 装入debug并运行
      • line19的作用
      • line4的作用
      • 改成全2
      • 改成全5
  • 实验任务6
    • 代码
    • 装入debug并调试
    • 运行前逻辑段
    • 运行后逻辑段
  • 实验任务7
    • 分析
    • 代码
    • 运行前的逻辑段
    • 运行后的逻辑段

实验任务1

任务1-1

ds = 076A; ss = 076B; cs = 076C;

X-2; X-1;

任务1-2

ds = 076A; ss = 076B; cs = 076C;

X-2; X-1;

任务1-3

ds = 076A; ss = 076C; cs = 076E;

X -4; X-2;

任务1-4

ds = 076C; ss = 076E; cs = 076A;

X + 2; X + 4;

任务1-5

问题一

\[\lceil N / 16\rceil * 16 个字节 \]

问题二

我的猜想是第四组代码(task1_4.asm)可以正确执行。在将上述4组代码最后的end start改为end之后,如果按照编译链接执行的顺序依次下来,结果仍然是什么都没有(因为没有对显存进行操作)。在这一过程中,三个步骤除了链接时会警告没有栈段之外(这个警告即使不修改代码也会出现),均不会出现警告。而在自行根据代码执行到上述实验所要求的那一行后,得到的dsss的值也相同,即都可以正确执行。唯一不同的在于cs,但是cs:ip最终指向的内存地址也相同。

其中,有区别的在于,由于没有指定代码段的起始地址,前三个都需要自行计算代码段,然后根据偏移地址用g命令执行程序。

这可能是因为程序是自顶向下执行,虽然没有从指定的代码段处开始,但是由于数据段和栈段是空的,所以不会影响后面的代码段。在这样的情境下,程序都会执行到终止的指令为止。虽然第四组代码的执行过程可能与修改前一致,但是由于栈段和数据段并没有会修改程序执行的指令,所以这四组代码最终都可以正确执行。

实验任务2

分析

b800:0f00~b800:0f9f这连续160字节依次重复填充十六进制数据03 04

由于是小端存储,所以十六进制数据0304代表的十六进制数0403h。这一十六进制数占2个字节,如果用循环语句来实现的话,就是要循环80次。

代码

assume cs:code
code segment
start:  mov ax, 0b800h
        mov ds, ax
        mov bx, 0f00h
        mov ax, 0403h
        mov cx, 80
s:      mov [bx], ax
        add bx, 2
        loop s

        mov ax, 4c00h
        int 21h
code ends
end start

截图

实验任务3

分析

由于这一程序是一个整体,那么三个数据段data1 data2 data3和代码段code应该是连续存储。前两个代码段长度不到16字节,那么按16字节存储。这样一来三个数据段的地址都明确了。可以让ds指向第一个数据段data1进行处理。而debug都是将程序从076A:0开始装入,那么可以认为第一个数据段哦才能够这里开始。

代码

assume cs:code
data1 segment
    db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends

data2 segment
    db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0       ; ten numbers
data2 ends

data3 segment
    db 16 dup(0)
data3 ends

code segment
start:  mov ax, 076ah 
        mov ds, ax
        mov bx, 0
        mov cx, 10
s:      mov ax, 0  
        add ax, [bx]
        add ax, [bx+10h]
        mov [bx+20h], ax 
        add bx, 1
        loop s

        mov ah, 4ch
        int 21h
code ends
end start

截图

装入debug并调试

运行前逻辑段

运行后逻辑段

实验任务4

代码

assume cs:code

data1 segment
    dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends 

data2 segment
    dw 8 dup(?)
data2 ends

code segment
start:  mov ax, data2
        mov ss, ax
        mov sp, 16
        mov ax, data1
        mov ds, ax
        mov bx, 0

        mov cx, 8
s:      mov ax, [bx]
        push ax
        add bx, 2
        loop s
    
        mov ah, 4ch
        int 21h
code ends
end start

截图

装入debug并调试

运行前逻辑段

运行后逻辑段

实验任务5

代码

assume cs:code, ds:data
data segment
        db 'Nuist'
        db 2, 3, 4, 5, 6
data ends

code segment
start:
        mov ax, data
        mov ds, ax

        mov ax, 0b800H
        mov es, ax

        mov cx, 5
        mov si, 0
        mov di, 0f00h
s:      mov al, [si]
        and al, 0dfh
        mov es:[di], al
        mov al, [5+si]
        mov es:[di+1], al
        inc si
        add di, 2
        loop s

        mov ah, 4ch
        int 21h
code ends
end start

运行结果

装入debug并运行

line19的作用

通过位与运算,将(从左到右)第三位转换为0,从而实现小写字母转换成大写字母

line4的作用

改成全2

改成全5

这里数值的作用应该是控制显存中内容的颜色

实验任务6

代码

assume cs:code, ds:data

data segment
    db 'Pink Floyd      '
    db 'JOAN Baez       '
    db 'NEIL Young      '
    db 'Joan Lennon     '
data ends

code segment
start:  mov ax, data
        mov ds, ax
        mov bx, 0
        mov cx, 4
s:      mov ax, [bx]
        or ax, 2020h 
        mov [bx], ax

        mov ax, [bx+2]
        or ax, 2020h
        mov [bx+2], ax

        add bx, 10h
        loop s

        mov ah, 4ch
        int 21h
code ends
end start

装入debug并调试

运行前逻辑段

运行后逻辑段

\[neil \space young, yyds! \]

实验任务7

分析

data段第一行5个数字,按字符存储,每个字符占1个字节,故一个数字占4个字节,第一行共占用20个字节,每一个数据要分两次移动。第二、第三行按字存储,每个数据固定占2个字节,每一个数据一次即可移动。table段初始化了5行16字节的空格。本题中用到的除法,除数占1个字即2个字节,共16位,那么被除数就需要占32位,即4个字节,高位放在dx中,低位放在ax中,由于被除数也是按字存储,所以dx初始化为0即可。

对于整个程序的控制是按照逻辑段table中格式进行。年分和收入需要4个字节,就用bx控制,循环末自加4。雇员数和人均收入需要2个字节,就用di控制,循环末自加2。

代码

assume cs:code, ds:data, es:table

data segment
    db '1975', '1976', '1977', '1978', '1979' 
    dw  16, 22, 382, 1356, 2390
    dw  3, 7, 9, 13, 28 
data ends

table segment
    db 5 dup( 16 dup(' ') )  ;
table ends

code segment
start:  mov ax, data
        mov ds, ax
        mov bx, 0
        mov ax, table
        mov es, ax
        mov ax, 0
        mov si, ax
        mov di, ax
        mov cx, 5
s:      mov ax, [bx]      
        mov es:[si], ax
        mov ax, [bx]+2
        mov es:[si]+2, ax
		
        mov dx, 0
        mov es:[si]+5, dx
        mov ax, [bx]+20
        mov es:[si]+7, ax
        
        div word ptr ds:[di]+30
        mov es:[si]+13, ax

        mov ax, [di]+30
        mov es:[si]+10, ax

        add di, 2
        add bx, 4
        add si, 16
        loop s

        mov ah, 4ch
        int 21h
code ends
end start

运行前的逻辑段

运行后的逻辑段

这里实际上由于题设的代码中收入是按字存储,所以实际上并没有必要在表格中给收入分配4个字节的存储空间,所以我把高两个字节初始化为了0,其他部分可以通过计算证明正确。



这篇关于汇编语言.实验2的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程