汇编学习--第六天

(5)

这道题的寄存器会不够,我们采取入栈出栈的方式来反复利用寄存器,这里的1,2,3定义的db,应该是"define byte",字节型数据

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
c segment
    db 0,0,0,0,0,0,0,0
c ends
code segment
start:    mov ax,a    ;a段地址
        mov ds,ax
        
        mov ax,b    ;b段地址
        mov es,ax
        
        mov cx,8    ;循环次数
        mov bx,0    ;交换数据的偏移地址
        mov ax,0    ;临时储存a+b的数据
s:        mov al,es:[bx]
        add al,[bx]
        
        push ds    ;ds入栈(这两处入栈相当于找了个地方,保存之前ds,bx的值)
        push bx    ;bx入栈
        mov bx,c    ;c段地址
        mov ds,bx
        pop bx        ;取出bx
        mov [bx],al    ;将a+b之和赋值给对应的c段地址数据
        pop ds        ;ds出栈,ds保存a段段地址
        inc bx        ;偏移地址+1
        loop s
        
        mov ax,4c00h
        int 21h
code ends
end start

(6)

先将a段数据入栈,再出栈,储存到b段对于位置

DS=075AH,所以程序入口地址在076AH,根据程序的代码,我们知道先a段,再b段,a段占16字,32字节(1f),所以076A:0H~076A:1FH都是a段数据,b段占8字,16字节,所以b段在076C:0H~076C:FH

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 es,ax
        
        mov bx,0
        mov cx,8
s0:        mov ax,[bx]
        push ax
        add bx,2
        loop s0
        
        mov bx,0
s1:        pop ax
        mov es:[bx],ax
        add bx,2
        loop s1
        
        mov ax,4c00h
        int 21h
code ends
end start

第七章 更灵活的定位内存地址的方法

强烈建议先去把8.1~8.4看了,因为你在这章写代码踩的,有关[...]的坑,在8.1~8.4都有说明

7.1 and和or指令

(1)and指令:逻辑与指令,按位进行与运算

mov al,01100011B
and al,00111011B

(2)or指令...

mov al,01100011B
or al,00111011B

7.2 关于ASCII码

7.3 以字符形式给出的数据

7.4 大小写转换问题

assume cs:codesg,ds:datasg
datasg segment
    db 'BaSiC'
    db 'iNfOrMaTiOn'
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov cx,5
        mov bx,0
        mov al,11011111b
s:        and ds:[bx],al
        inc bx
        loop s
        
        mov cx,11
        mov bx,0
        mov al,00100000b
s0:        or ds:[bx],al
        inc bx
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

7.5 [bx+idata]

指令

mov ax,[bx,200]     ;(ax) = ( (ds) * 16 + (bx) + 200)

等于

mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200

问题 7.1

(ax)=00beh

(bx)=1000h

(cx)=0606h

7.6 用[bx+idata]的方式进行数组的处理

assume cs:codesg,ds:datasg
datasg segment
    db 'BaSiC'
    db 'MinIX'
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov cx,5
        mov bx,0

s:        mov al,11011111b        
        and ds:[bx],al
        mov al,00100000b
        or ds:5[bx],al
        inc bx
        loop s
        
        mov ax,4c00h
        int 21h
codesg ends
end start

7.7 SI 和 DI

si和di是8086CPU中和bx功能相近的寄存器si和di不能分成两个8位寄存器

mov bx,0
mov ax,[bx]

mov si,0
mov ax,[si]

mov di,0
mov ax,[di]

问题 7.2

书上代码:

assume cs:codesg,ds:datasg
datasg segment
    db 'welcome to masm!'
    db '................'
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        mov si,0
        mov di,16
        
        mov cx,8
s:        mov ax,[si]
        mov [di],ax
        add si,2
        add di,2
        loop s
        
        mov ax,4c00h
        int 21h
codesg ends
end start

写的:

assume cs:codesg,ds:datasg
datasg segment
    db 'welcome to masm!'
    db '................'
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
    
        mov si,0
        mov cx,16
s:        mov al,[si]
        mov [si+16],al
        inc si
        loop s
    
        mov ax,4c00h
        int 21h
codesg ends
end start

不能直接给段寄存器赋值,要使用普通寄存器,不能给段存储器:[偏移地址]使用直接赋值或者段寄存器赋值,这和前面的段寄存器一样的。

问题 7.3

和自己写的7.2一样

7.8 [bx+si] 和 [bx+di]

[bx+si]也可以写成[bx][si]

mov ax,[bx+si]

mov ax,[bx][si]

问题 7.4

(ax)=00BEH

(bx)=1000H

(cx)=0606H

7.9 [bx+si+idata] 和 [bx+di+idata]

mov ax,[bx+200+si]

mov ax,[200+bx+si]

mov ax,200[bx][si]

mov ax,[bx].200[si]

mov ax,[bx][si].200

问题 7.5

ax=0006h

cx=6a00h

bx=226ah

7.10 不同的寻址方式的灵活应用

问题 7.6

开头字母都在偏移地址3

assume cs:codesg,ds:datasg
datasg segment
    db '1. file         '
    db '2. edit         '
    db '3. search       '
    db '4. view         '
    db '5. options      '
    db '6. help         '
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov si,3
        mov cx,6
        mov al,11011111b
s:        and [si],al
        add si,10h
        loop s
        
        mov ax,4c00h
        int 21h
codesg ends
end start

问题 7.7

assume cs:codesg,ds:datasg
datasg segment
    db 'ibm             '
    db 'dec             '
    db 'var             '
    db 'vec             '
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov si,0
        mov cx,4

s0:        mov dx,cx
        mov bx,0
        mov cx,3
s:        mov al,11011111b
        and  [bx+si],al
        inc bx
        loop s
        add si,10h
        mov cx,dx
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

 在上面的程序中,使用dx来临时储存外层循环cx的值,如果寄存器不够怎么办?两种方法

1.入栈出栈

assume cs:codesg,ds:datasg
datasg segment
    db 'ibm             '
    db 'dec             '
    db 'var             '
    db 'vec             '
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov si,0
        mov cx,4

s0:        push cx
        mov bx,0
        mov cx,3
s:        mov al,11011111b
        and  [bx+si],al
        inc bx
        loop s
        add si,10h
        pop cx
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

上面这个是自己写的,虽然能够得出正确答案,但是最好定一个栈空间

assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
    db 'ibm             '
    db 'dec             '
    db 'var             '
    db 'vec             '
datasg ends
stacksg segment
    dw 0,0,0,0,0,0,0,0
stacksg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        mov ax,stacksg
        mov sp,15
        mov ss,ax
        
        mov si,0
        mov cx,4

s0:        push cx
        mov bx,0
        mov cx,3
s:        mov al,11011111b
        and  [bx+si],al
        inc bx
        loop s
        add si,10h
        pop cx
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

第二种,cx放入内存空间

assume cs:codesg,ds:datasg
datasg segment
    db 'ibm             '
    db 'dec             '
    db 'var             '
    db 'vec             '
    dw 0            ;有段空间才能使用
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov si,0
        mov cx,4

s0:        mov ds:[40h],cx        ;必须加上ds
        mov bx,0
        mov cx,3
s:        mov al,11011111b
        and  [bx+si],al
        inc bx
        loop s
        add si,10h
        mov cx,ds:[40h]        ;必须加上ds
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

为什么在[40h]必须加上ds,不然运行失败?

因为在这里,我们使用另一个段寄存器来储存cx数据,而使用[40h]默认是ds段寄存器的地址,但我们储存cx的段寄存器不一定是ds,可以命名其他的,所以需要加上。(见 8.3-(3) ))

问题 7.9

SI源变址寄存器,DI目地变址寄存器,两者不能同时在[...]中使用,具体看点击1--点击2

assume cs:codesg,ds:codesg
datasg segment
    db '1. display      '
    db '2. brows        '
    db '3. replace      '
    db '4. modify       '
    dw 0
datasg ends
codesg segment
start:    mov ax,datasg
        mov ds,ax
        
        mov bx,0
        mov cx,4
        
s0:        mov ds:[40],cx
        mov di,3    ;注意开始位置
        mov cx,4
        
s:        mov al,11011111b
        and [bx+di],al
        inc di
        loop s
        add bx,10h
        mov cx,ds:[40h]
        loop s0
        
        mov ax,4c00h
        int 21h
codesg ends
end start

实验 6  实践课程中的程序

前面已做

第八章 数据处理的两个基本问题

reg(寄存器):ax, bx, cx, dx, ah, al, bh, bl, ch, cl, dh, dl, sp, bp, si, di;

sreg(段寄存器): ds, ss, cs, es;

8.1 bx,si,di和bp

https://www.cnblogs.com/Mayfly-nymph/p/11079189.html

8.2  机器指令处理的数据在什么地方

机器指令进行数据处理:读取,写入,运算

指令执行前,数据可存在于:CPU内部,内存,端口

机器码 汇编指令 指令执行前数据的位置
8E1E0000 mov bx,[0] 内存,ds:0单元
89C3 mov bx,ax CPU内部,ax寄存器
BB0100 mov bx,1 CPU内部,指令缓冲器

8.3 汇编语言中数据位置的表达

(1)立即数

直接包含在机器指令的数据(执行前在CPU的指令缓冲器)

mov ax,1

add ax,5

or ax,00100000b

mov bl,'a'

(2)寄存器

指令要处理的数据在寄存器中,也就是给出寄存器

mov ax,bx

mov ds,ax

push bx

mov ds:[0],bx

push ds

mov ss,ax

mov sp,ax

(3)段地址(SA)和偏移地址(EA)

指令要处理在内存中的数据,可以用[X]的指令给出EA,SA在某个段寄存器中

段地址默认在ds中的

mov ax,[0]

mov ax,[di]

mov ax,[bx+di+8]

段地址默认在ss中的

mov ax,[bp]

mov ax,[bp+8]

mov ax,[bp+si+8]

显性给出段寄存器地址

mov ax,ds:[bp]

mov ax,es:[bx]

mov ax,ss:[bx+si]

mov ax,cs:[bx+si+8]

  

猜你喜欢

转载自www.cnblogs.com/Mayfly-nymph/p/11074771.html