base64编码器设计汇编语言实现(中南大学汇编语言课程设计)

请参考IDA的反汇编结果或自行查阅相关资料,使用汇编语言编写一个简单的base64编码程序,能够将一个文件的内容编码成base64的形式并保存于该文件中(假定该文件内只有ASCII字符,不超过20字节)。

根据题目要求,编写了一个执行输入输出的base64编码程序,经过调试可以正常运行各种不同情况的base64编码转换。

1. 整体思路

base64编码算法是一种与ASCII编码算法不同的编码算法,ASCII编码转换为base64编码的方法如下图所示:
在这里插入图片描述

通过base64编码的转换步骤,我们得知转换过程实际上是将每3位ASCII 码对应的24位二进制编码分成四部分,再在前面补0后即得到4位的base64 编码。我们以此原理为核心,编写将输入的字符串转变为base64编码输出。

2. 完整代码

data segment
	base64 db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",'$'
    encode db 31 dup(0);编码后最多28个编码字符+2个'='+1个'$'
    ctrl   db 13,10,'$'
    scanf label byte;缓冲区
		max   db  22
    	act   db  ?
    	ascii db  22 dup(0)
data ends


code segment
  main proc far
 	assume cs:code,ds:data
  start:
  	;预处理
  	push ds 	
  	sub ax,ax
  	push ax
  	mov ax,data
  	mov ds,ax

  	;获取ASCII字符到缓冲区(不超过20个)
  	mov ah,0ah 	;dos功能调用10号字符串输入:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示器显示
    lea dx,scanf
    int 21h

    ;计算循环几次(字符数除3向上取整)
    sub ax,ax 	;ax清零
    mov al,act 	;实际输入字符数
    mov bl,3 	;除数
    div bl 		;ax除以操作数,商放在al中,余数放在ah中(需要提前将被除数放在ax中)
    mov dh,ah 	;备份保存
    cmp ah,0 	;比较ah和0,若相同,则ZF=1
    jz next 	;如果ah=0(余数为0)则跳过下一步到next指令
    inc al 		;如果ah!=0(余数不为0)则将循环次数加一,末尾补0
    
    
next:
	;循环预处理
	mov ch,al 	;计数器ch次,不使用cl是因为在移位时要使用cl存移位数
	mov si,0 	;指向待处理的ASCII码,使用寄存器相对寻址,类似于高级语言数组访问,步长以字节为单位
	mov di,0 	;指向编码后的base64码

;循环cl次,将3个ASCII码转化成4个base编码
loop1:
	;获得第一个base码(第一个ASCII码的高6位)
	mov al,ascii[si];将第一位ASCII码存入al,再存入ah备份
	mov ah,al
	inc si 		;指向下一个ASCII码
	mov cl,2 	;右移两位预处理
	shr al,cl 	;逻辑右移两位,得到第一个base64码al
	mov bl,al 	;将得到的第1个base码存入bl
	mov bh,0 	;将bl存入为bx(使用bx的寄存器相对寻址方式)
	mov dl,base64[bx];将对应的base64码字母存入dl
	mov encode[di],dl;再存入内存,encode可看作解码的数组,di指向某位置
	inc di 		;指向下一个应存入的位置
	
	;获得第二个base码(第一个ASCII码的低两位+第二个ASCII码的高四位)
	mov cl,6 	;逻辑左移预处理
	shl ah,cl 	;将第一个ASCII码左移6位使最低2位到最高2位,低位清零
	mov cl,2 	;逻辑右移预处理
	shr ah,cl 	;使高两位右移两位到第3、4位,高位低位都清零
	mov al,ascii[si];将第二位ASCII码存入al
	mov cl,4 	;逻辑右移预处理
	shr al,cl 	;将第2个ASCII码右移4位使最高4位到最低4位,高位清零
	add al,ah 	;将两个数相加,得到第二个base64码al
	mov bl,al 	;将得到的第2个base码存入bl
	mov bh,0 	;将bl存入为bx
	mov dl,base64[bx];将对应的base64码字母存入dl
	mov encode[di],dl;再存入内存
	inc di 		;指向下一个应存入的位置

	;获得第三个base码(第二个ASCII码的低四位+第三个ASCII码的高两位)
	mov al,ascii[si];将第二位ASCII码存入al
	inc si
	mov cl,4
	shl al,cl
	mov cl,2
	shr al,cl
	mov ah,ascii[si];将第三位ASCII码存入ah
	mov cl,6
	shr ah,cl
	add al,ah 	;将两个数相加,得到第3个base64码al
	mov bl,al 	;将得到的第3个base码存入bl
	mov bh,0 	;将bl存入为bx
	mov dl,base64[bx];将对应的base64码字母存入dl
	mov encode[di],dl;再存入内存
	inc di 		;指向下一个应存入的位置

	;获得第四个base码(第三个ASCII码的低6位)
	mov al,ascii[si];将第三位ASCII码存入al
	inc si
	mov cl,2
	shl al,cl
	mov cl,2
	shr al,cl	;逻辑右移两位,得到第4个base64码al
	mov bl,al 	;将得到的第4个base码存入bl
	mov bh,0 	;将bl存入为bx
	mov dl,base64[bx];将对应的base64码字母存入dl
	mov encode[di],dl;再存入内存
	inc di 		;指向下一个应存入的位置

	;下一步判断
	dec ch 		;循环次数减一
	cmp ch,0 	;判断循环次数是否为0
	jnz loop1 	;不为0则继续循环


	;结尾处理
	sub di,2 
	cmp dh,1 	;如果余数不为1
	jnz next2 	;就跳转下一步判断
	mov al,'=' 	;余数为1,先加一个‘=’
	mov encode[di],al
next2:
	inc di
	cmp dh,0 	;如果余数为0
	jz next3 	;就跳转结束
	mov al,'='
	mov encode[di],al ;余数为1或者2,再加一个‘=’
	
next3:
	inc di
	mov al,'$'
	mov encode[di],al

	;输出结果
	lea dx,ctrl 	;回车换行
	mov ah,9
	int 21h 		;将当前数据区中以‘$’结尾的字符串送显示器显示
	lea dx,encode 	
	mov ah,9
	int 21h

  	ret
  main endp

code ends
end start

3. 代码释义

(1) 数据段(1-9行)
设立base64编码表、回车换行功能、存储输入的ASCII 码和输出的base64编码的区域以及dos10号调用的缓冲区等内容。

(2) 预处理与输入字符(10-27行)
代码段伪指令设立、汇编程序预处理以及通过dos10号调用从键盘获取输入的字符串。

(3) 循环预处理(28-45行)

  • 计算循环次数
    被除数为存入的字符串长度,除数根据base64的转换过程设定为3,得到商——循环次数及余数——尾处理的依据,将得到的结果分别存入al与ah寄存器中。

  • 对于商的处理原则如下:
    a. 若ah=0(余数为0),则循环次数恰好为商。
    b. 若ah≠0(余数不为0),则将商加1,循环次数为商+1。

  • 循环预处理(设立计数器ch记录循环次数,设立si与di用于遍历字符串内容进行读取和存入)。

(4) 主代码(46-109行)
将字符串按照base64转换规则转换。

  • 处理的思想是通过各种操作将24个二进制位的ASCII码单元(每单元3个ASCII码)转换为4个base64编码存入encode[di]中
  • 循环判断
    每完成一次处理部分会让ch计数器内的循环次数自减,自减完成后判断循环次数是否为0。若循环次数不为0则跳回处理部分继续循环,若循环次数为0则代表字符串全部处理完成,并转入结尾处理部分。

(5) 结尾处理(110行-140行)

  • 结尾base64码处理部分
    由于如果字符个数不是3的整数倍的话,需要在后面补0。按照base64的原则全为0的字符需用=代替,但00000000的base64 编码为A,因此会导致出现bug。所以为修正尾部设计结尾base64码处理部分,保证输出正确的base64编码。
  • 尾处理部分
    在字符串的最后存入一个$表示字符串结束。完成后最后
    通过dos9号调用先回车换行再输出转换后的base64编码,完成输出。

4. 运行结果

输入三种类型(余数为0、余数为1、余数为2)的字符串的运行结果,对比base64在线转换器的结果,可见三种字符串结果均相同,可以说明编写的汇编程序正确的完成了base64编码。

  • masm过程
    在这里插入图片描述

  • link过程
    在这里插入图片描述

  • 余数为0的字符串(以Man为例,标准结果应为TWFu)
    在这里插入图片描述

  • 余数为1的字符串(以A为例,结果应为QQ==)
    在这里插入图片描述

  • 余数为2的字符串(以BC为例,结果应为QkM=)
    在这里插入图片描述

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forest_Lamb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值