(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]