概述

什么是机器语言、汇编语言、高级语言?汇编语言的优、缺点?

  1. 机器语言(Machine Language):
    • 定义: 机器语言是计算机可以直接执行的二进制代码。每个指令和数据都以二进制形式表示。
    • 优点: 最直接地与计算机硬件交互,执行效率高。
    • 缺点: 难以理解、编写和维护,对于不同的计算机体系结构不可移植。
  2. 汇编语言(Assembly Language):
    • 定义: 汇编语言是一种低级编程语言,使用助记符(mnemonics)来代替机器语言中的二进制指令。每个助记符对应一个特定的机器语言指令。
    • 优点: 相对于机器语言更容易理解,同时保留了对计算机硬件的直接控制。
    • 缺点: 与平台相关,可读性较差,开发效率低,不易移植。
  3. 高级语言(High-Level Language):
    • 定义: 高级语言是相对于汇编语言和机器语言而言的,更接近人类语言的一种编程语言。典型的高级语言有C、C++、Java、Python等。
    • 优点: 开发效率高,可读性强,可移植性好。
    • 缺点: 通常执行效率较低,因为需要通过编译器或解释器转换为机器语言。

小基础

  • 正数的原码、反码、补码都相同,负数的反码是符号位不变,其余取反,补码是反码加1。
  • 正数与负数相加时,是对补码进行相加。
  • 数字1的ASCII值是49,字母A的是65,小写字母a的是97。
  • 逻辑运算中:
    • ADD:同一为一。
    • OR:同零为零。
    • XOR:不同为一。
    • NOT:取反。

基础

8086微处理器内部包含14个16位寄存器,按功能分为以下四类:

  1. 通用寄存器:

    • AX(累加器)
    • BX(基址寄存器)
    • CX(计数器)
    • DX(数据寄存器)
  2. 指针寄存器:

    • SP(堆栈指针)
    • BP(基址指针)
    • SI(源变址寄存器)
    • DI(目的变址寄存器)
  3. 段寄存器:

    • CS(代码段寄存器)
    • DS(数据段寄存器)
    • SS(堆栈段寄存器)
    • ES(附加段寄存器)
  4. 标志寄存器:

    • flags(标志寄存器)

在计算机中,执行二进制加法操作涉及到进位(Carry)、溢出(Overflow)以及其他标志位的判断。对于给定的 A 和 B 的二进制表示:

  1. A = 01001101
  2. B = 11101001

进行 A + B(使用补码相加) 操作:

  01001101   (A)
+ 11101001 (B)
__________
00110110 (Sum)

得到二进制和十进制的结果都是 00110110。下面我们来判断标志位的状态值:

  • CF(Carry Flag,进位标志): 没有进位,CF=0。
  • PF(Parity Flag,奇偶标志): 00110110 中1的个数为4,为偶数,PF=1。
  • AF(Adjust Flag,调整标志): 不考虑此标志位。
  • ZF(Zero Flag,零标志): 结果不为零,ZF=0。
  • SF(Sign Flag,符号标志): 结果为正数,SF=0。
  • OF(Overflow Flag,溢出标志): 由于我们在这里进行的是无符号整数加法,因此不存在溢出,OF=0。

综上,各标志位的状态值为:

  • CF=0
  • PF=1
  • AF=(不考虑)
  • ZF=0
  • SF=0
  • OF=0

注意双字单元与单字单元的区别,一个单元是2个字节

写出存储单元物理地址的计算公式,已知逻辑地址为358FH:5234H,计算此存储单元的物理地址是多少?

对于逻辑地址358FH:5234H:

  1. 将段地址左移四位:[ 358FH << 4 = 358F0H ]
  2. 加上偏移地址:[ 358F0H + 5234H = 3AB24H ]

因此,物理地址为3AB24H。

指令系统

寻址方式

这种寻址方式包括直接寻址、寄存器寻址、立即寻址、寄存器间接寻址等。

  1. 直接寻址: 操作数的地址直接给出,通常是一个常数。

    MOV AX, [1234H]  ; 将内存地址1234H处的值加载到寄存器AX中
  2. 寄存器寻址: 操作数的地址存放在一个寄存器中。

    MOV AX, BX  ; 将寄存器BX中的值加载到寄存器AX中
  3. 立即寻址: 操作数的数值直接给出,而不是地址。

    MOV AX, 5678H  ; 将立即数5678H加载到寄存器AX中
  4. 寄存器间接寻址: 操作数的地址存放在一个寄存器中,该寄存器的内容是目标地址。

    MOV AX, [BX]  ; 将内存地址BX处的值加载到寄存器AX中

指令系统1

PUSH一下,SP的值减2,POP一下,SP的值加2

指令系统2

移位操作符

假设初始时 AX 的值为 1234HCL 的值为 4

  1. 执行 SHL AX, 1,逻辑左移 AX 一位:

    1234H  (初始值)
    2468H (左移一位)

    (AX) = 2468H

  2. 执行 SAL AX, CL,算术左移 AX 4 位,移动的位数由 CL 决定:

    2468H  (初始值)
    4680H (左移四位)

    (AX) = 4680H

  3. 执行 SHR AX, 1,逻辑右移 AX 一位:

    4680H  (初始值)
    2340H (右移一位)

    (AX) = 2340H

  4. 执行 SAR AX, CL,算术右移 AX 4 位,移动的位数由 CL 决定:

    2340H  (初始值)
    F234H (右移四位,符号位填充)

    (AX) = F234H

所以,执行完这些指令后:

  • (AX) = 2468H(SHL AX, 1)

  • (AX) = 4680H(SAL AX, CL)

  • (AX) = 2340H(SHR AX, 1)

  • (AX) = F234H(SAR AX, CL)

  • SHL逻辑左移

  • SAL算数左移

  • 这俩效果一样

  1. SHR逻辑右移
  2. SAR算数右移 算数右移会保持符号位不变,最高位(符号位)的值被用来填充右移操作后的空位。
  3. ROL 循环左移
  4. ROR 循环右移
  5. RCL 带进位循环左移

汇编语言

程序结构

伪指令

汇编语言源程序的基本框架结构

DSEG SEGMENT ; 数据段定义

DSEG ENDS ; 数据段结束

CSEG SEGMENT ; 代码段定义
ASSUME CS:CSEG,DS:DSEG ; 假定 CS 寄存器指向代码段,DS 寄存器指向数据段

START: ; 程序入口标签
MOV AX,DSEG ; 将数据段地址加载到 AX 寄存器
MOV DS,AX ; 将 DS 寄存器设置为数据段地址



MOV AH,4CH
INT 21H

CSEG ENDS ; 代码段结束

END START ; 程序结束

常用操作符

  1. TYPE: 用于获取数据的类型。

  2. LENGTH: 用于获取字符串的长度。

  3. SIZE: 用于获取数据或变量的大小。

对于给定的数据定义:

FLDB DB ?
TABLEA DW 20 DUP (?), 10 DUP (0)
TABLEB DB "ABCD"

执行以下 MOV 指令后,相关寄存器的内容如下:

  1. MOV AX, TYPE FLDB:

    • AX 中加载 1,因为 FLDB 是一个字节变量。
  2. MOV AX, TYPE TABLEA:

    • AX 中加载 2,因为 TABLEA 是一个字(2 字节)的数组。
  3. MOV CX, LENGTH TABLEA:

    • CX 中加载 30,因为 TABLEA 有 20 个字和 10 个字节,总共是 30 个元素。
  4. MOV DX, SIZE TABLEA:

    • DX 中加载 60,因为 TABLEA 有 20 个字,每个字占用 2 字节,总共是 40 字节,再加上 10 个字节。
  5. MOV CX, LENGTH TABLEB:

    • CX 中加载 4,因为 TABLEB 是一个包含 4 个字符的字符串。

上机过程

以下是DEBUG中常用的一些命令及其对应的中文单词:

  1. R (Registers - 寄存器): 查看/修改寄存器内容。
  2. D (Dump - 显示): 显示内存内容。
  3. E (Enter - 编辑): 编辑内存内容。
  4. G (Go - 运行): 运行程序。
  5. T (Trace - 跟踪): 跟踪程序执行。
  6. U (Unassemble - 反汇编): 反汇编。
  7. Q (Quit - 退出): 退出DEBUG。

语句

顺序

  1. 简答题: 请编写一个完整的源程序,计算以下表达式的值:[ W = X * Y - Z + 12 ],其中 ( X, Y, Z ) 均为有符号字节数据,初始值自行设定,并将结果存放在字变量 ( W ) 中。
DSEG SEGMENT ; 数据段定义
X DW 5
Y DW 10
Z DW 5
ANS DW ?
DSEG ENDS ; 数据段结束

CSEG SEGMENT ; 代码段定义
ASSUME CS:CSEG,DS:DSEG ; 假定 CS 寄存器指向代码段,DS 寄存器指向数据段

START: ; 程序入口标签
MOV AX,DSEG ; 将数据段地址加载到 AX 寄存器
MOV DS,AX ; 将 DS 寄存器设置为数据段地址

MOV AX,X
IMUL Y
; 乘法的积是32位的,不能直接与后面的数字相加减
MOV CX,AX
MOV BX,DX
; 把Z进行符号拓展
MOV AX,Z
CWD

SUB CX,AX
SBB DX,0

ADD CX,12
ADC DX,12

MOV ANS,AX
MOV ANS+2,DX

MOV AH,4CH
INT 21H

CSEG ENDS ; 代码段结束

END START ; 程序结束

分支

这是x86汇编语言中的一些条件跳转指令。以下是它们的含义:

  1. JMP (Jump): 无条件跳转,直接转移到指定的地址。

  2. JZ (Jump if Zero): 如果零标志位(ZF)为1,则跳转。

  3. JE (Jump if Equal): 如果等于标志位(ZF)为1,则跳转。

  4. JNZ (Jump if Not Zero): 如果零标志位(ZF)为0,则跳转。

  5. JNE (Jump if Not Equal): 如果等于标志位(ZF)为0,则跳转。

  6. JS (Jump if Sign): 如果符号标志位(SF)为1,则跳转。

  7. JNS (Jump if Not Sign): 如果符号标志位(SF)为0,则跳转。

  8. JO (Jump if Overflow): 如果溢出标志位(OF)为1,则跳转。

  9. JNO (Jump if Not Overflow): 如果溢出标志位(OF)为0,则跳转。

这些指令允许根据特定的条件跳转到不同的代码段,根据标志位的状态决定是否执行跳转。

什么是无符号数?

无符号数是一种数值表示方法,它只包含非负整数,即零和正整数,没有符号位表示正负。在无符号数系统中,所有的数都被认为是非负的。

这是x86汇编语言中的一些条件跳转指令,用于处理无符号数(Below Above)的比较。以下是它们的含义:

  1. JB (Jump if Below): 如果无符号数的下界条件满足(CF=1),则跳转。

  2. JNB (Jump if Not Below): 如果无符号数的下界条件不满足(CF=0),则跳转。

  3. JBE (Jump if Below or Equal): 如果无符号数的下界条件满足或等于(CF=1或ZF=1),则跳转。

  4. JNBE (Jump if Not Below or Equal): 如果无符号数的下界条件既不满足也不等于(CF=0且ZF=0),则跳转。

这些指令主要用于处理无符号数的比较和条件跳转。

这是x86汇编语言中的一些条件跳转指令,用于处理带符号数(Less Great)的比较。一般都是有符号数,以下是它们的含义:

  1. JL (Jump if Less): 如果带符号数小于条件满足(SF ≠ OF),则跳转。

  2. JNL (Jump if Not Less): 如果带符号数小于条件不满足(SF = OF),则跳转。

  3. JLE (Jump if Less or Equal): 如果带符号数小于或等于条件满足(SF ≠ OF 或 ZF=1),则跳转。

  4. JNLE (Jump if Not Less or Equal): 如果带符号数小于或等于条件不满足(SF = OF 且 ZF=0),则跳转。

这些指令主要用于处理带符号数的比较和条件跳转。

循环

(填空题)

DEC CX
JNZ ABC

以上两条指令,可以用

LOOP ABC

指令来替代。

例2:试编写程序,从自然数1开始累加,一直加到累加和大于5050为止。同时,统计被累加的自然数的个数,并将统计的结果存放到M单元。

子程序

特别感谢

也不知道哪个好人给的5角钱,哈哈哈哈,3q🤣🤣🤣🤣