32位汇编语言学习笔记(24)--HexDump程序

来源:互联网 发布:js定义数组 编辑:程序博客网 时间:2024/06/02 05:50


此程序的目的是把输入的文本字符转换成16进制的格式输出。

SECTION .bss                    ; Section containing uninitialized data

        BUFFLEN equ 16              ;We read the file 16 bytes at a time

        Buff:      resb BUFFLEN ; Text buffer itself

SECTION .data                           ; Section containing initialised data

        HexStr:    db " 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00",10

        HEXLENequ $-HexStr

        Digits:     db "0123456789ABCDEF"

SECTION .text                   ; Section containing code

global     _start                         ; Linker needs this tofind the entry point!

_start:

        nop                    ; This no-op keeps gdbhappy...

; Read a buffer full of text from stdin:

Read:

        moveax,3                 ; Specify sys_readcall

        movebx,0                 ; Specify FileDescriptor 0: Standard Input

        movecx,Buff            ; Pass offset of thebuffer to read to

        movedx,BUFFLEN            ; Pass number ofbytes to read at one pass

        int80h                       ; Call sys_readto fill the buffer

        movebp,eax            ; Save # of bytes readfrom file for later

        cmpeax,0                 ; If eax=0,sys_read reached EOF on stdin

        jleDone            ; Jump If equal or below(to 0, from compare)

;Set up the registers for the process buffer step:

        mov esi,Buff             ; Place address of file buffer into esi

        mov edi,HexStr                 ; Place address of line string into edi

        xor ecx,ecx               ; Clear line string pointer to 0


;Go through the buffer and convert binary values to hex digits:

Scan:

        xor eax,eax               ; Clear eax to 0


;Here we calculate the offset into the line string, which is ecx X 3

        mov edx,ecx             ; Copy the pointer into line string into edx

        lea edx,[edx*2+edx]

;Get a character from the buffer and put it in both eax and ebx:

        mov al,byte [esi+ecx]      ; Put a byte from the input buffer intoal

        mov ebx,eax             ; Duplicate the byte in bl for second nybble


;Look up low nybble character and insert it into the string:

        and al,0Fh                    ; Mask outall but the low nybble

        mov al,byte [Digits+eax]  ; Look up the char equivalent of nybble

        mov byte [HexStr+edx+2],al ; Write thechar equivalent to line string


;Look up high nybble character and insert it into the string:

        shr bl,4             ; Shift high 4 bits of char into low 4 bits

        mov bl,byte [Digits+ebx] ; Look up charequivalent of nybble

        mov byte [HexStr+edx+1],bl ; Write thechar equivalent to line string


;Bump the buffer pointer to the next character and see if we're done:

        inc ecx              ;Increment line string pointer

        cmp ecx,ebp   ; Compare to the number of characters in the buffer

        jna Scan  ; Loop back if ecx is <= number of chars in buffer

; Write the line of hexadecimal values tostdout:

        moveax,4                 ; Specify sys_writecall

        movebx,1                 ; Specify FileDescriptor 1: Standard output

        movecx,HexStr                ; Pass offsetof line string

        leaedx,[ebp*2+ebp]; Pass size of the line string

        int80h                       ; Make kernelcall to display line string

        jmpRead         ; Loop back and load filebuffer again

; All done! Let's end this party:

Done:

        moveax,1                 ; Code for ExitSyscall

        movebx,0                 ; Return a code ofzero   

        int80H                       ; Make kernelcall


这个程序在3个系统调用上的代码与前面大小写转换程序的代码类型,下面主要分析标记为绿色的代码,这部分代码用于把输入字符转换成16进制数输出:

 

mov esi,Buff //esi = Buff

mov edi,HexStr //edi=HexStr

xor ecx,ecx //ecx清零。

 

Scan:

xor eax,eax //eax清零。

 

mov edx,ecx //edx = ecxecx0开始,用于循环计数。

lea edx,[edx*2+edx] //edx = 3*edx = 3*ecx

 

mov al,byte [esi+ecx] //al = Buf[ecx]

mov ebx,eax //ebx = eax,这样bl=al

 

and al,0Fh //al0x0F进行与运算,清除高4位,保留低4位。

mov al,byte [Digits+eax] //al = Digits[eax]

mov byte [HexStr+edx+2],al //HexStr[3*ecx+2]= al

 

shr bl,4 //逻辑右移4位,左边空出的位填0,这样bl的低4位就是原来高4位的值。

mov bl,byte [Digits+ebx] //bl = Digits[ebx]

mov byte [HexStr+edx+1],bl //HexStr[3*ecx +1]= bl

 

inc ecx //ecx自增

cmp ecx,ebp //比较ecxebp(读入Buf的字节个数)

jna Scan //如果ecx小于等于ebp,跳转到Scan,继续循环。

 

makefile文件:

hexdump1: hexdump1.o

        ld-o hexdump1 hexdump1.o

hexdump1.o: hexdump1.asm

        nasm-f elf -g -F stabs hexdump1.asm

 

测试:

[root@bogon hexdump1]# ./hexdump1

abcde

 6162 63 64 65 0A

0 0
原创粉丝点击