跳转至

实验整理

以下是修改和排版后的文本:


0. 数据类型认知

本实验要求比较10个1万以内的数字,这些数字将存储在一个数组中。

  • BYTE:1个字节,最大值为FF,即255。
  • WORD:2个字节,最大值为FFFF,即65535。

为了最小化空间开支,本实验中将使用WORD数据类型。

类比C++创建数组的方式,在汇编代码中数组是顺序存储的,以下是数组的定义方式:

; 定义一个已经初始化好的数组
table DWORD 10h, 20h, 30h, 40h ; 这个table就是一个符合要求的数组(即一维数组)

; 定义一个没有初始化的数组 - 数组名 命令 元素个数 dup(?)
barray WORD 20 dup(?)

数组访问方式

我们需要了解如何访问这些数组,以下是一些基本操作集合:

  1. 获取指定位置的数组元素 例如,要存储table数组的第一个元素,可以使用相对地址的技巧:
mov esi, 1
mov eax, [table + esi * 2] ; 以table的地址位置做相对地址偏移,代表了table[b]的含义
  1. 实现数组元素的修改和转换 为了实现数组元素的修改,我们可以使用交换的方式:
mov esi, pAdarray

L2:
    mov eax, [esi]
    cmp eax, [esi + 2]
    jl L3 ; 如果小于,则跳转到L3,重新开始循环
    xchg eax, [esi + 2]
    mov [esi], eax

1. 实现条件判断

在汇编语言中仿照C++的if-else语句,可以使用cmp指令结合条件跳转指令:

cmp dword ptr ds:[var1], 20     ; 判断var1是否大于20
jl L1                            ; 不大于则跳转到L1

cmp dword ptr ds:[var2], 100    ; 判断var2是否小于100
jg L1                            ; 不小于则跳转到L1

底层原理阐述CMP(比较)指令执行隐含的减法操作,但不修改任何操作数。对于无符号数字,机器通过ZF(零标志)和CF(进位)标志位来确定比较结果;而对于有符号数字,则通过OF(溢出)和SF(符号)标志位的状态来比较。

2. 循环的构建

循环的构建可以采用模块化的思维,创建一个循环控制结构:

L3:
    add esi, 2
    loop L2

    pop ecx
    loop L1

一般来说,循环体的伪代码结构如下:

MOV CX, 5         ; 设置循环次数为5次
LOOP_START:
    ; 循环体代码
    ; 在这里执行需要重复的操作
    DEC CX         ; 循环次数减1
    JNZ LOOP_START  ; 如果CX寄存器不为0,则继续循环

3. 利用堆栈模拟C++函数模块

如果要在汇编代码中实现C++函数,并成功传入参数:

void BubbleSort(int *arr, int length); // 传入数组的指针和数组的长度

在汇编中,我们通常通过将参数压入栈中来实现,编写如下的过程(PROC):

FunctionName PROC
    ; 填充函数主体,使用ESP寄存器访问栈顶以调取函数参数
FunctionName ENDP

.code
MAIN PROC

    push num2              ; 压入第二个参数
    push num1              ; 压入第一个参数
    call FunctionName      ; 调用函数
    mov result, eax        ; 将返回的结果存储到result变量中

    ; 结束程序
    invoke ExitProcess, 0

MAIN ENDP
END MAIN

这样排版后,内容更清晰,逻辑更通顺,适合导入Word文档。如果有其他需要调整的部分,请告诉我!