Huo 加密/解密汇编程序
x8086 汇编程序,使用基本的汇编语言思想,通过键盘输入加密/解密文本。

引言
汇编语言是一种允许您更底层地与计算机通信的编程语言。本文的目的是介绍一个用汇编语言编写的用于加密/解密文本的小项目。这绝不是一个深入的汇编手册。这里只简要讨论汇编语言中更基础的方面。
本项目将介绍 8/16 位处理器非常基本的汇编指令的使用。这里展示的程序是一对加密/解密程序。用户只需输入,Huo11.exe 程序就会立即加密他输入的内容。用户可以使用解密程序 (Huo12.exe) 执行相反的操作(解密加密的消息)。按下 'q' 键可终止程序。
为什么要读这个?嗯,有一句古老的佛教谚语说:“当学生准备好时,老师就会出现。” 我不是老师。如果你不愿意做学生,那就走开,去读点别的吧。图形和声音通常更有趣……
必备组件
为了能够使用此程序,您将需要
- NASM 汇编器,可以从 http://www.nasm.us/ 下载。
- ALINK 链接器,可以从 http://alink.sourceforge.net/ 下载。
- 一个简单的文本编辑器(例如记事本)来编写您的程序。
- 用于您超现代计算机的 DOS 模拟器(它可以做很多事情,但它不允许您自己做很多事情……)
请注意,对于较新版本的 Windows,您可能需要 DOS 模拟器才能运行这些程序。一个好的模拟器是 DoxBox,可以从 http://www.dosbox.com/ 下载。请参阅文章开头的图片,了解如何将驱动器挂载到 DosBox 并从 cmd 启动 NASM。
分布式
您可以从这里下载以下内容
- “加密”程序 (Huo11.asm) 的代码和最终的可执行文件 (Huo11.exe)
- “解密”程序 (Huo12.asm) 的代码和最终的可执行文件 (Huo12.exe)
- 我用来编译和链接程序的 ALINK 链接器和 NASM16 汇编器(附带手册)
汇编语言简介
为了控制计算机,您必须控制其内存。它的电路存储着臭名昭著的 0 和 1,如果您改变它们,您就改变了计算机“思考”的方式。计算机中的内存以特定方式存储。了解那种方式,您就知道如何编程。如何做到?很简单!阅读手册。这听起来可能像是愚蠢的建议,但事实并非如此。每个处理器都有自己的数据存储方式和内存模式。您只需要阅读制造商的手册来学习它。
我将在此描述的是 x8086 处理器在旧 DOS 时代内存的组织方式。为什么这有用?因为内存实际上如何组织并不重要。技术每天都在变化!最重要的是要学会适应这个不断变化的世界。学习 x8086 处理器的内存模型,您将轻松学会 x80386 处理器的内存模型。做到这一点,进入 Windows 7 / Pentium 时代也将不再是问题。关键不在于死记硬背现在事物是如何工作的,因为明天它们将以不同的方式工作。关键在于学会不害怕学习新事物。
内存段
8086/8088 处理器的内存被组织成大的段。在这些段内,存在更小的区域。因此,要引用内存中的特定区域,您所要做的就是写下大段的“地址”以及在该段内的偏移量,以到达您想要的特定区域。
内存地址的形式为 TTTT:MMMM,其中 TTTT 是段,MMMM 是段内的偏移量。
寄存器
内存的一些重要区域有名称。这些特殊位置称为寄存器。8086/8088 处理器系列的主要寄存器是
8086/8088 处理器寄存器组
名称 | 类别 | 目的 |
AX | 通用 | 累加器 |
BX | 通用 | Base |
CX | 通用 | 计数器 |
DX | 通用 | Data |
SI | 目录 | 源索引 |
DI | 目录 | 目标索引 |
SP | 堆栈 | 堆栈指针 |
BP | 堆栈 | 基址指针 |
CS | 节 | 代码段 |
DS | 节 | 数据节 |
SS | 节 | 堆栈段 |
ES | 节 | 附加段 |
IP | 指令指针 | |
FLAGS | 函数标志 |
您可以使用 move 命令将数据移入这些寄存器(即这些寄存器代表的段)。例如,命令...
mov DS, AX
...将 AX 内存段中的数据移入 DS 段。
这些寄存器可用于执行特定任务。例如
- DS 寄存器指向程序的数据段。如果我们用命令
mov ax,data
和mov ds,ax
将我们程序的数据段加载到 DS 寄存器中,然后在 DX 寄存器中加载我们数据特定数据元素(变量)的偏移量(例如,一个名为 help 的变量,命令为mov dx,hello
),那么地址DS:DX
就指向hello
变量的特定内存地址。
另一个重要的内存区域是堆栈。在该区域,您可以 **push** 数据或 **pop** 它们以便再次使用。
中断
DOS 或 BIOS 的操作系统有一些特定的命令,称为中断,可以通过……(惊喜!)INT
命令调用!
例如,命令...
INT 21h
...告诉程序查看 AH
寄存器中存储的值,以确定它将执行什么操作。
为了将文本消息打印到屏幕,您必须使用以下部分中粗体显示的命令
Segment code start: mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,stacktop mov dx, hello mov ah,9 int 0x21 mov ax,0x4c00 int 0x21 segment data hello: db 'hello, world', 13, 10, '$' segment stack stackresb 64 stacktop:
我们将值 9 加载到 AX 寄存器,然后调用中断 0x21 (21h)。中断 21h 的调用例程 9 是一个 DOC 程序,它将在屏幕上显示存储在 DS:DX 地址中的内存地址中的数据。
一、加密程序
此程序的代码在此处
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,enkey
add dl, ah
mov ah,2
int 0x21
jmp main1
done:
mov ax,0x4c00
int 0x21
segment data
segment stack stack
resb 64
stacktop:
让我解释一下。
命令...
mov ah,00
int 16h
...指示程序等待用户输入按键(这就是中断
16h
在 AH 寄存器存储 0x00
时所做的事情)。按下的键存储在 DL 寄存器中,使用命令:mov dl,al
。
命令...
cmp al, 'q'
jz done
...检查按键的值,如果用户按下了 'q
' 键,则程序跳转到终止它的命令(见下文)。
命令...
mov ax,0x4c00
int 0x21
...是终止程序的命令(这就是中断 0x21
在 AX 寄存器中为 0
时所做的事情)。
如果用户输入的字符不是 'q
',则程序会将 DL
中存储的值更改为加上 5
(它实际上转移了 enkey
变量的长度,即 5
– 我只是为了自己实验的目的这样做)
mov ah,enkey
add dl, ah
然后它会在屏幕上显示新的结果字符值。
mov ah,2
int 0x21
二、解密程序
为了解密消息,您只需要做相反的事情:只需从输入的字符中减去 5
!该程序的代码在此处
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,-5
add dl, ah
mov ah,2
int 0x21
jmp main1
done:
mov ax,0x4c00
int 0x21
segment data
segment stack stack
resb 64
stacktop:
一般来说,您可以在记事本中创建一个简单的汇编代码文件,并将其保存为所需的任何名称,扩展名为“.asm”。编写完程序后,您所要做的就是编译它,然后链接它。
三、HuoCodec
我将加密和解密功能合并到一个名为 HuoCodec 的程序中。该程序的源代码实际上是上述程序的超集。
segment code
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,stacktop
%define encoderkey 'hello'
%strlen enkey encoderkey
main1:
mov dx,info1
mov ah,9
int 0x21
mov dx,info2
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
mov dx,message1
mov ah,9
int 0x21
mov dx,message2
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
select:
mov ah,00
int 16h
mov dl,al
cmp al, '1'
jz encrypt
cmp al,'2'
jz decrypt
encrypt:
mov dx,message3
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
main_encrypt:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,enkey
add dl, ah
mov ah,2
int 0x21
jmp main_encrypt
decrypt:
mov dx,message4
mov ah,9
int 0x21
mov dx,blankline
mov ah,9
int 0x21
main_decrypt:
mov ah,00
int 16h
mov dl,al
cmp al, 'q'
jz done
mov ah,-enkey
add dl, ah
mov ah,2
int 0x21
jmp main_decrypt
done:
mov ax,0x4c00
int 0x21
segment data
info1: db 'Huo CoDec - Programmed by Spiros Kakos (Huo)', 13, 10, '$'
info2: db '(c) Copyright 2005 - All rights reserved', 13, 10, '$'
blankline: db ' ', 13, 10, '$'
message1: db '1 - Encrypt message', 13, 10, '$'
message2: db '2 - Decrypt message', 13, 10, '$'
message3: db 'Encrypting mode (q to exit)...', 13, 10, '$'
message4: db 'Decrypting mode (q to exit)...', 13, 10, '$'
segment stack stack
resb 64
stacktop:
编译程序
在 DOS 命令行环境中(那个黑白屏幕,我们的孩子不幸只能在百科全书中看到,因为现在孩子们用电脑所做的一切就是浏览、浏览和……哦,浏览……),您必须输入适当的命令来将用汇编语言 (asm) 编写的程序编译成目标文件(.obj 文件,由汇编指令助记符组成的操作码)。汇编文件必须与汇编器(在本例中是 NASM)位于同一目录中。
NASM 编译命令
nasm-f obj [filename] (e.g. nasm-f obj hello. asm)
链接程序
使用 ALINK 将目标文件链接成一个可执行文件,方法是输入命令 ALINK file2.obj file3.obj –oEXE
(或直接 ALINK [文件名]),以便将 file2.obj 和 file3.obj 文件链接成一个 EXE 文件(例如,ALINK hello.obj
)。
结论
继续实验!并且请记住,在向其他程序员询问如何做之前,先自己玩玩代码。因为这才是真正造就优秀程序员的。