编写汇编

定义一个段

  • segment和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时,必须要用到的一对伪指令。
  • segment和ends的功能是定义一个段,segment说明一个段的开始,ends说明一个段的结束。
  • 一个段必须有一个名称来表示,使用格式为:
    • 段名 segment
    • 段名 ends
  • 一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当做栈空间来使用。
  • 一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。

    end

  • end是汇编程序的结束标记,如果碰到伪指令end,就结束对源程序的编译。

  • 程序写完了,在结尾加上伪指令end,不然无法知道程序何时结束。

    assume

  • 他假设某一段寄存器和程序中的某一个用segment···ends定义的段相关联。

  • 通过assume说明这种关联,在需要的情况下,编译程序可以将段寄存器和某一个具体的段相联系。

    汇编源程序

    伪指令(编译器处理)
    汇编指令(编译为机器码)
    程序:源程序中最终由计算机执行、处理的指令或数据。

    源程序

    任务:编写运算2^3。 ``` assume cs:abc

abc segment mov ax,2 mov bx,2 mul ax mul bx

mov ax,4c00H int 21H abc ends

end abc ends

end

  1. <a name="d2WDm"></a>
  2. #### 程序返回
  3. 应该在程序的末尾添加返回的程序段。<br />mov ax,4c00H<br />int 21H<br />这两台指令所实现的功能就是程序返回。
  4. <a name="jzfRO"></a>
  5. ## 多个段的程序
  6. - 对于使用多个段的问题:编程计算以下4个数据的和,结果存放在ax寄存器中。0123H,0456,0123H,0123H
  7. - 在一个段中存放数据、代码、栈

assume cs:codesg codesg segment tong:
dw 0123H,0123H,0123H,0123H,0123H,0123H,0123H,0123H,0123H xor bx,bx xor ax,ax
mov cx,9h s: add ax,cs:[bx] add bx,2
loop s

  1. mov ax,4c00H
  2. int 21H

codesg ends end tong

  1. dw:定义字型数据。define word 16b。<br />在程序的第一条指令的前面加上了一个标号start,而这个标号在伪指令end的后面出现。<br />end出了通知编辑器程序结束之外,还可以通知编译器程序的入口在什么地方。
  2. - 将一段数据放入栈中,实现逆序存放

assume cs:codesg codesg segment start:
dw 0ffffH,0123H,0123H,0123H,0123H,0123H,0123H,0123H
dw 0,0,0,0,0,0,0,0

  1. mov bx,0
  2. mov cx,8
  3. s: push cs:[bx]
  4. add bx,2
  5. loop s
  6. mov cx,8
  7. mov bx,0
  8. s0: pop cs:[bx]
  9. add bx,2
  10. loop s0
  11. mov ax,4c00H
  12. int 21H

codesg ends end start

  1. - 将数据、代码、栈放入不同的段
  2. - 如果数据、栈和代码需要的空间超过64KB,就不能放在一个断中。8086模式的限制,不是每个处理器都是这样。

assume cs:code,ds:data,ss:stack

data segment dw 0ffffH,0123H,0123H,0123H,0123H,0123H,0123H,0123H
data ends

stack segment dw 0,0,0,0,0,0,0,0 stack ends

code segment start:
mov ax,stack 分配栈空间 mov ss,ax mov sp,16 设置栈顶ss:sp stack:16 mov ax,data 分配data空间 mov ds,ax ds指向data段 mov bx,0
mov cx,8 s: push [bx] add bx,2 loop s

  1. mov cx,8
  2. mov bx,0
  3. s0: pop [bx]
  4. add bx,2
  5. loop s0
  6. mov ax,4c00H
  7. int 21H

code ends end start

  1. 就是秀~~~我也太强了。
  2. - 代码段、数据段、栈段完全是我们自己定义的。
  3. - 用来存放数据段的:data
  4. - 用来存放代码段的:code
  5. - 用来存放栈空间的:stack
  6. <a name="Hv3vK"></a>
  7. ## and&or
  8. 这个太简单了,没啥好写的。
  9. <a name="opaaf"></a>
  10. ## ASCII码
  11. - 世界上很多编码方案,ASCII是计算机通常被采用的
  12. - 编码就是一套规则,用干什么样的信息来表示现实对象
  13. - 比如61H表示'a'
  14. - mov al,'a'相当于mov al,61H
  15. - 大小写转换

code segment start:
mov al,’A’ or al,20h and al,0dfh

  1. mov ax,4c00H
  2. int 21H

code ends end start

  1. <a name="Sp0Av"></a>
  2. ## [bx+idata]
  3. - mov ax,[bx+200]的含义
  4. - 将一个内存单元的内容送入ax,这个内存单元的长度为2字节,存放一个字,偏移地址为bx中的数据加上200,段地址在ds中。
  5. - 数学化描述:mov ax,[bx+200]=((ds)*16+(bx)+200)
  6. - 数组的处理

datasg segment db ‘abcdefghijklm’ db ‘nopqrstuvwxyz’ datasg ends

code segment start:
mov ax,datasg mov ds,ax mov bx,0
mov cx,13 s: mov al,[bx] and al,11011111b mov [bx],al
mov al,[bx+13] —[bx+13]可以表示为13[bx],是不是特别像数组 and al,11011111b mov [bx+13],al inc bx loop s

  1. mov ax,4c00H
  2. int 21H

code ends end start

  1. <a name="DWnuy"></a>
  2. ## SI&DI
  3. - SI和DI是8086CPU中与BX功能相近的寄存器,但是SI和DI不能够分成两个8位寄存器来使用。
  4. - 将“tong ge shuai bi”用si,di复制到“................”中

datasg segment db ‘tong ge shuai bi’ db ‘…………….’ datasg ends

code segment start:
mov ax,datasg mov ds,ax mov si,0
mov di,13 mov cx,13 s: mov al,[si] mov [di],al inc di inc si loop s

  1. mov ax,4c00H
  2. int 21H

code ends end start

  1. <a name="XghvJ"></a>
  2. ## 不同的寻址方式和灵活应用
  3. - 几种定位内存地址的方法
  4. - [iata]用一个常量来表示地址,可用于直接定位一个内存单元
  5. - [bx]用一个变量来表示内存地址,可用于间接定位一个内存单元
  6. - [bx+idata]用一个变量和常量表示地址,可在一个起止的基础上用变量间接定位一个内存单元
  7. - [bx+si]用两个变量表示地址
  8. - [bx+si+idata]用两个变量和一个常量表示地址
  9. - 讲前四个字母换成大写字母

stack segment dw 0,0,0,0,0,0,0,0 stack ends

datasg segment db ‘tonggeshuai…..’ db ‘deyipi……….’ datasg ends

code segment start:
mov ax,datasg mov ds,ax
mov ax,stack mov ss,ax xor bx,bx
mov cx,2 s0:push cx mov cx,4 xor si,si s1:mov al,[bx+si]
and al,11011111b mov [bx+si],al inc si loop s1 pop cx add bx,10h
loop s0

  1. mov ax,4c00H
  2. int 21H

code ends end start

  1. 实现了双重循环。吊的一批~~~~
  2. <a name="yOjOK"></a>
  3. ## 寄存器集合
  4. - reg:axbxcxdxahalbhblchcldhdlspbpsidi
  5. - sregdssscses
  6. - 8086寄存器中,只有bxbpsidi可以用在[...]中进行内存寻址
  7. - 在[...]中只能以四个组合出现
  8. - bx&sibx&dibp&sibp&di
  9. - 指令中没有设置段地址(ds没给值),[bp]的段地址默认给ss的段
  10. - mov ax,[bp]=((ss)*16+bp)
  11. <a name="fCrw6"></a>
  12. ## 寻址方式
  13. 关于DEC公司的一条记录:<br />公司名称:DEC 在内存中如下存放<br />总裁姓名:Ken Olsen seg:60+00<br />排 名:137 'DEC'<br />收 入:40 +03 <br />著名产品:PDP 'ken slsen'<br />2021年同哥的加入公司有了新变化: +0C
  14. 1. Ken Olsen在富翁榜上的排名已升至38位; 137
  15. 1. DEC的收入增加了70亿美元; +0E
  16. 1. 该公司的著名产品已变为VAX系列计算机。 40
  17. 任务:编程修改内存中的过时数据。 +10 <br /> 'PDP'

code segment start:
mov bx,60h mov si,0 mov word ptr [bx+0Ch],137d mov word ptr [bx+0Eh],40d mov byte ptr [bx+10h+si],’P’ inc si mov byte ptr [bx+10h+si],’D’ inc si mov byte ptr [bx+10h+si],’P’ inc si

  1. xor si,si
  2. mov word ptr [bx+0ch],38d
  3. mov ax,[bx+0eh]
  4. add ax,70d
  5. mov word ptr [bx+0eh],ax
  6. mov byte ptr [bx+10h+si],'V'
  7. inc si
  8. mov byte ptr [bx+10h+si],'A'
  9. inc si
  10. mov byte ptr [bx+10h+si],'X'
  11. inc si
  12. mov ax,4c00H
  13. int 21H

code ends end start

  1. <a name="reOHz"></a>
  2. ## div指令
  3. - div是触发指令,使用div作触发的时候:
  4. - 除数:8位或16位,在寄存器或内存单元中
  5. - 被除数:(默认)放在ax或dx和ax中
  6. - 除数 被除数
  7. - 8位 16位(ax)
  8. - 16位 32位(dx+ax)
  9. - 结果:运算 8位 16位
  10. 商 AL AX<br /> 余数 AH DX
  11. - div byte ptr ds:[0]
  12. - (al)=(ax)/((ds)*16+0)的商
  13. - (ah)=(ax)/((ds)*16+0)的余数
  14. - div word ptr es:[0]
  15. - (ax)=[(dx)*10000H+(ax)]/((ds)*16+0)的商
  16. - (dx)=[(dx)*10000H+(ax)]/((ds)*16+0)的余数
  17. - 利用除法指令计算100001/100

code segment start:
mov dx,1h mov ax,86a1h mov bx,100h
div bx

  1. mov ax,4c00H
  2. int 21H

code ends end start

  1. 伪指令dd
  2. - dbdw定义字节型数据和字型数据。
  3. - dd是用来定义dworddouble word双字)型数据的。
  4. - db 1:01H
  5. - dw 1:00 01H
  6. - dd 1:00 00 00 01H

code segment start:
mov bx,0h
mov si,0h mov [bx+si],word ptr 86a1h add si,2h mov [bx+si],word ptr 1h add si,2h mov [bx+si],word ptr 100d
add si,2h mov [bx+si],word ptr 0d

  1. mov ax,[0]
  2. mov dx,[2]
  3. div word ptr [4]
  4. mov [6],ax
  5. mov ax,4c00H
  6. int 21H

code ends end start
```

dup

  • db 3 dup(0)
    • 定义了3个字节,都为0
    • 0,0,0
  • db 3 dup(0,1,2)
    • 定义了9个字节
    • 0,1,2,0,1,2,0,1,2
  • db 3 dup(‘abc’,’ABC’)
    • 定义了18个字节
    • abcABCabcABCabcABC