3 汇编语言编程

学习笔记
作者: MingXiao

3.1 汇编语言编写程序的工作过程

一个完整的汇编程序示例:

assume cs:codesg
codesg segment

mov ax, 0123H
mov bx, 0456H
add ax, bx
add ax, ax

mov ax, 4c00H
int 21H

codesg ends
end

其中首尾是伪指令,不被CPU执行,但需要编译器执行

倒数第二段相当于return 0,表示程序返回

第二,三段为CPU执行的汇编指令

段分配语句:assume cs:code, ds:data, ss:stack

段名 segment,表示一个段的开始,将内容写入该段内

段名 ends,表示一个段的结束

end,表示程序结束

可执行文件生成过程

记事本写.asm,masm生成.obj,link生成.exe

在编写一个程序的过程中,会得到包括.obj,.lst,.crf,.map在内的中间结果

用debug装载程序

在没有指定DS时,会自动装载CS前的**256(100H)**个字节,作为数据区

故此时CS=DS+10H,CX寄存器的值等于代码的长度

注意程序在int 21处结束,后续为垃圾值

p,g命令

P在遇到子程序,中断时,直接执行所有结果(t时逐条执行)

G可以指定开始运行的代码,直到遇到断点或程序结束

3.2 LOOP指令

实现循环的指令

CPU在收到loop指令时,依次执行以下操作:

  1. CX = CX - 1
  2. CX == 0

当CX=0时,循环结束;CX=n,则程序执行n次;CX需要在循环之前指定值,且不能为0(否则执行65536次)

loop程序需要定义一个标号,从标号处到loop,循环

3.3 段前缀

在访问内存单元的指令中,要显示地用段前缀指明

mov al, [0]
mov bl, [0]

最终得到的al=bl=00H,此时需要改为如下

mov al, ds:[0]
mov bl, ss:[0]

例:计算ffff:0~ffff:b内所有值的和的方法

解:add dx, ds:[0]?不行,此时为字型数据相加

​ add dl, ds:[0]?不行,会溢出

​ 解决方案

mov bx, 0
mov cx, 0bH
s:	mov al, ds:[bx]
mov ah, 0
add dx, ax
inc bx #bx += 1
loop s

安全存放数据

在段地址指定,运行时由OS分配空间

可以将CS,DS,SS指定为一个段地址,一般不这么干

3.4 将数据写入代码段

示例代码:

assume cs:code
code segment

dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H

start: mov ax,0
         mov bx, 0h
         mov cx, 8

     s: add ax,cs:[bx]
         add bx,2
         loop s

         mov ax,4c00h
         int 21h

code ends
end start

其中 dw表示定义字型数据(define word),还有db(define byte),dd(define double)

start:

end start

这个代码段包裹代码,主要是end后的符号和:前的符号需要统一名称

end除了告知结束外,还告知编译器程序代码的入口,与数据做区分



Comments