[解码后输出的链接。 ] [1]代码开始很好然后变为bezerk然后恢复正常。它旨在将base64 nasm转换为其原始形式。我将收到的第一个字节(在rax寄存器中的ASCII中)转换为Base64以获得二进制等效值。为两位腾出空间,然后在rbx中取下一个字节并执行相同的操作。然后获取rbx中的前两位并添加到第一个字节以获取ASCII等效值并保存结果。由于此问题,我无法使用=
处理文件末尾。
谢谢你的帮助。
; Build using these commands:
; nasm -f elf64 -g -F dwarf decode.asm
; ld -o decode decode.o
%macro writeIt 0
add al,bl ; add bl to al because upper rbx contains the rest
mov byte[B64LIN+rcx-1],al ; move the equivalent into B64LIN
%endmacro
; ************************************************************************
;;; Note: This process does automatic conversion into ASCII ##############
; ************************************************************************
%macro clear 1
xor %1,%1
%endmacro
SECTION .bss ; Section containing uninitialized data
BUFFLEN equ 4
Buff: resb BUFFLEN
SECTION .data ; Section containing initialised data
B64LIN: db "000",0 ; used for output
B64LEN: EQU $-B64LIN ; only used to determine the size of the string treated
SECTION .text ; Section containing code
;;; We convert ASCII to Base 64
Base64:
.UpperCase: ; remove 65 to convert match the B64Table
sub rax,65
ret
.LowerCase: ; remove 71 to convert match the B64Table
sub rax,71
ret
.Numbers: ; add 4 for numbers
add rax,4
ret
.Addition: ; remove 62 to convert match the B64Table
sub rax,62
ret
.BackSlash: ; remove 63 to convert match the B64Table
sub rax,63
ret
;------------------------------------------------------------------------
; Encode: Enconde binary datas into Base 64
; UPDATED: 15/12/2017
; IN: File
; RETURNS: ASCII VERSION
; MODIFIES: ASCII to Base 64
;;; Behaves like a switch statement
;;; Look for the equivalent Base64
Convert:
cmp rax,61h
jge Base64.LowerCase
cmp rax,41h
jge Base64.UpperCase
cmp rax,3Dh
je .EOF1
cmp rax,30h
jge Base64.Numbers
cmp rax, 2Bh
je Base64.Addition
cmp rax,2Fh
je Base64.BackSlash
cmp rax,rbx ; comparing rbx to rax for zeros
je Exit ; we're done if that happens
; *****************************************************************************
;;; Note: This process doesn't send any values back because it was added to the
;;; file in the encoding process. ##############
; *****************************************************************************
.EOF1:
clear rax
writeIt
ret
;;; Register clean up
Decode:
;;; Treating 1st Byte
mov al,byte[Buff+rcx] ; takes in the first element in the input
call Convert ; convert to get their Base64 value
;;; Treating 2nd Byte
inc rcx ; increment to get the next element in the Buff
mov bl,byte[Buff+rcx] ; moves second element into rbx
xchg al,bl ; xchg rax with rbx because Convert deals with rax
call Convert ; call Convert to get the base64 equiv.
xchg bl,al ; get the values back and exchange them
rol rax,2 ; make room for the first 2 bits in rbx
ror rbx,4 ; keep only the top four since first 2 bits are 00
writeIt
clear bl ; clear bl so we can role back
rol rbx,8 ; role 8 so we already make room when we moves rax
;;; Treating 3rd Byte
inc rcx ; increment to get the next element
mov al,byte[Buff+rcx] ; moves it directly into al since previous element is gone
call Convert ; Converts to Base64
ror rax,2 ; roll right to get the top 4 bits only
xchg rax,rbx ; xchg so even the top bits are kept in the process
writeIt
;;; Treating 4th Byte
clear bl ; clear lower 4 bits
clear rax ; clears everything since we have no use for it
inc rcx ; increments to get next
mov al,byte[Buff+rcx] ; moves next Byte into al
call Convert ; converts to Base64 equiv.
rol rbx,8 ; make room for last 2 bits coming
writeIt
ret
;;; code keeps on running onto PrintLine to finish off
;-------------------------------------------------------------------------
; IN: Nothing
; RETURNS: The Original text
; MODIFIES: Nothing
; CALLS: Kernel sys_write
PrintLine:
push rax ; Save all used registers
push rbx ; Save all used registers
push rcx ; Save all used registers
push rdx ; Save all used registers
mov rax,4 ; Specify sys_write call
mov rbx,1 ; Specify File Descriptor 1: Standard output
mov rcx,B64LIN ; Pass offset of line string
mov rdx,B64LEN ; Pass size of the line string
int 80h ; Make kernel call to display line string
pop rdx ; Restore all caller's registers
pop rcx ; dito
pop rbx ; dito
pop rax ; dito
ret ; Return to caller
;-------------------------------------------------------------------------
LoadBuff:
push rax ; Save caller's EAX
push rbx ; Save caller's EBX
push rdx ; Save caller's EDX
mov rax,3 ; Specify sys_read call
mov rbx,0 ; Specify File Descriptor 0: Standard Input
mov rcx,Buff ; Pass offset of the buffer to read to
mov rdx,BUFFLEN ; Pass number of bytes to read at one pass
int 80h ; Call sys_read to fill the buffer
mov rbp, rax ; Save # of bytes read from file for later
xor rcx,rcx ; Clear buffer pointer ECX to 0
pop rdx ; Restore caller's EDX
pop rbx ; Restore caller's EBX
pop rax ; Restore caller's EAX
ret ; And return to caller
GLOBAL _start
; ------------------------------------------------------------------------
; MAIN PROGRAM BEGINS HERE
;-------------------------------------------------------------------------
_start:
; We will stay into this loop until the buffer is empty
Read:
call LoadBuff ; Read first buffer of data from stdin
cmp rbp,0 ; If ebp=0, sys_read reached EOF on stdin
jbe Exit ; If ebp=0, we jumps to Exit
call Decode ; If there's still some data into the buffer, we call Encode to convert them
call PrintLine ; Save the enconded data into stdout
clear rbp ; Clear ebp for the next LoadBuff
jmp Read ; Read one more time the data from stdi
; The programm did his job, we can exit
Exit:
xor rax, rax ; Clear rax
xor rbx, rbx ; Clear rbx
mov rax,1 ; Code for Exit Syscall
mov rbx,0 ; Return a code of zero
int 0x80 ; Make kernel call`
[1]: https://i.stack.imgur.com/bHJnI.jpg