32位汇编语言学习笔记(27)--HexDump3程序

来源:互联网 发布:mac软件宝箱10.7.5 编辑:程序博客网 时间:2024/05/18 14:28
HexDump2程序还可以再改进,通过提取公共函数到一个单独的文件,HexDump2原来的代码被分解到两个asm文件中:hexdump3.asm和
textlib.asm。

因为分解为两个文件,互相间的符号引用需要通过EXTERN和GLOBAL这两个关键字。

EXTERN声明符号是其他模块的外部符号,GLOBAL声明本模块的符号是全局符号,其他模块可见。

以下是hexdump3.asm源码,相对于书中的程序,我做了少量改动:

;  Executable name : hexdump3;  Version         : 1.0;  Created date    : 4/15/2009;  Last update     : 4/20/2009;  Author          : Jeff Duntemann;  Description     : A simple hex dump utility demonstrating the use of;separately assembled code libraries via EXTERN;;  Build using these commands:;    nasm -f elf -g -F stabs hexdump3.asm;    ld -o hexdump3 hexdump3.o <path>/textlib.o;SECTION .bss; Section containing uninitialized dataBUFFLEN EQU 10Buff:resb BUFFLENSECTION .data; Section containing initialised dataSECTION .text; Section containing codeEXTERN ClearLine, DumpChar, PrintLine, DUMPLENGLOBAL _start_start:nop; This no-op keeps gdb happy...nopxor esi,esi; Clear total chars counter to 0; Read a buffer full of text from stdin:Read:mov eax,3; Specify sys_read callmov ebx,0; Specify File Descriptor 0: Standard Inputmov ecx,Buff; Pass offset of the buffer to read tomov edx,BUFFLEN; Pass number of bytes to read at one passint 80h; Call sys_read to fill the buffermov ebp,eax; Save # of bytes read from file for latercmp eax,0; If eax=0, sys_read reached EOF on stdinjbe Done; Jump If Equal (to 0, from compare); Set up the registers for the process buffer step:xor ecx,ecx; Clear buffer pointer to 0; Go through the buffer and convert binary values to hex digits:Scan:xor eax,eax; Clear EAX to 0mov al,byte[Buff+ecx]; Get a char from the buffer into ALmov edx,esi; Copy total counter into EDXand edx,0000000Fh; Mask out lowest 4 bits of char countercall DumpChar; Call the char poke procedure; Bump the buffer pointer to the next character and see if buffer's done:inc ecx; Increment buffer pointerinc esi; Increment total chars processed countercmp ecx,ebp; Compare with # of chars in bufferjb .modTest; If we've processed all chars in buffer...test esi,0000000Fhjnz .loadBuffcall PrintLinecall ClearLine.loadBuff:jmp Read; If we've done the buffer, go get more; See if we're at the end of a block of 16 and need to display a line:.modTest:test esi,0000000Fh  ; Test 4 lowest bits in counter for 0jnz Scan; If counter is *not* modulo 16, loop backcall PrintLine; ...otherwise print the linecall ClearLine; Clear hex dump line to 0'sjmp Scan; Continue scanning the buffer; All done! Let's end this party:Done:call PrintLine; Print the "leftovers" linemov ecx,DUMPLENmov eax,1; Code for Exit Syscallmov ebx,0; Return a code of zeroint 80H; Make kernel call

以下是textlib.asm的源码:

;  Executable name : textlib;  Version         : 1.0;  Created date    : 4/10/2009;  Last update     : 9/2/2010;  Author          : Jeff Duntemann;  Description     : A linkable library of text-oriented procedures and tables;;  Build using these commands:;    nasm -f elf -g -F stabs textlib.asm;SECTION .bss; Section containing uninitialized dataBUFFLEN EQU 10Buffresb BUFFLENSECTION .data; Section containing initialised data; Here we have two parts of a single useful data structure, implementing the; text line of a hex dump utility. The first part displays 16 bytes in hex; separated by spaces. Immediately following is a 16-character line delimited; by vertical bar characters. Because they are adjacent, they can be; referenced separately or as a single contiguous unit. Remember that if; DumpLin is to be used separately, you must append an EOL before sending it; to the Linux console.GLOBALDumpLin, HexDigits, BinDigits  ;Data itemsGLOBAL  DumpLength, ASCLength, FullLength, DUMPLEN  ;Equate exportsDumpLin:db " 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "DUMPLENEQU $-DumpLinASCLin:db "|................|",10ASCLENEQU $-ASCLinFULLLENEQU $-DumpLin; The equates shown above must be applied to variables to be exported:DumpLength:dd 3ASCLength:dd ASCLENFullLength:dd FULLLEN; The HexDigits table is used to convert numeric values to their hex; equivalents. Index by nybble without a scale: [HexDigits+eax]HexDigits:db "0123456789ABCDEF"; This table allows us to generate text equivalents for binary numbers. ; Index into the table by the nybble using a scale of 4: ; [BinDigits + ecx*4]BinDigits:db "0000","0001","0010","0011"db "0100","0101","0110","0111"db "1000","1001","1010","1011"db "1100","1101","1110","1111"; This table is used for ASCII character translation, into the ASCII; portion of the hex dump line, via XLAT or ordinary memory lookup. ; All printable characters "play through" as themselves. The high 128 ; characters are translated to ASCII period (2Eh). The non-printable; characters in the low 128 are also translated to ASCII period, as is; char 127.DotXlat: db 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,2Ah,2Bh,2Ch,2Dh,2Eh,2Fhdb 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h,3Ah,3Bh,3Ch,3Dh,3Eh,3Fhdb 40h,41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fhdb 50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch,5Dh,5Eh,5Fhdb 60h,61h,62h,63h,64h,65h,66h,67h,68h,69h,6Ah,6Bh,6Ch,6Dh,6Eh,6Fhdb 70h,71h,72h,73h,74h,75h,76h,77h,78h,79h,7Ah,7Bh,7Ch,7Dh,7Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Ehdb 2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2Eh,2EhSECTION .text; Section containing codeGLOBALClearLine, DumpChar, Newlines, PrintLine  ;Procedures;-------------------------------------------------------------------------; ClearLine: Clear a hex dump line string to 16 0 values; UPDATED:4/13/2009; IN: Nothing; RETURNS:Nothing; MODIFIES: Nothing; CALLS:DumpChar; DESCRIPTION:The hex dump line string is cleared to binary 0. ClearLine:push edx; Save caller's EDXmov edx,15; We're going to go 16 pokes, counting from 0.Poke:mov eax,0; Tell DumpChar to poke a '0'call DumpChar; Insert the '0' into the hex dump stringsub edx,1; DEC doesn't affect CF!jae .Poke; Loop back if EDX >= 0pop edx; Restore caller's EDXret; Go home;-------------------------------------------------------------------------; DumpChar: "Poke" a value into the hex dump line string.; UPDATED:4/13/2009; IN: Pass the 8-bit value to be poked in EAX.;     Pass the value's position in the line (0-15) in EDX ; RETURNS:Nothing; MODIFIES: EAX; CALLS:Nothing; DESCRIPTION:The value passed in EAX will be placed in both the hex dump;portion and in the ASCII portion, at the position passed ;in ECX, represented by a space where it is not a printable ;character.DumpChar:push ebx; Save EBX on the stack so we don't trashpush edi; First we insert the input char into the ASCII portion of the dump linemov bl,byte [DotXlat+eax]; Translate nonprintables to '.'mov byte [ASCLin+edx+1],bl; Write to ASCII portion; Next we insert the hex equivalent of the input char in the hex portion; of the hex dump line:mov ebx,eax; Save a second copy of the input charlea edi,[edx*2+edx]; Calc offset into line string (ECX X 3); Look up low nybble character and insert it into the string:and eax,0000000Fh   ; Mask out all but the low nybblemov al,byte [HexDigits+eax]   ; Look up the char equivalent of nybblemov byte [DumpLin+edi+2],al ; Write the char equivalent to line string; Look up high nybble character and insert it into the string:and ebx,000000F0h; Mask out all the but second-lowest nybbleshr ebx,4; Shift high 4 bits of char into low 4 bitsmov bl,byte [HexDigits+ebx] ; Look up char equivalent of nybblemov byte [DumpLin+edi+1],bl ; Write the char equiv. to line string;Done! Let's go home:pop edi; Restore caller's EDI register valuepop ebx; Restore caller's EBX register valueret; Return to caller;-------------------------------------------------------------------------; Newlines: Sends between 1-15 newlines to the Linux console; UPDATED:4/13/2009; IN: # of newlines to send, from 1 to 15; RETURNS:Nothing; MODIFIES: Nothing; CALLS:Kernel sys_write; DESCRIPTION:The number of newline chareacters (0Ah) specified in EDX;is sent to stdout using using INT 80h sys_write. This;procedure demonstrates placing constant data in the ;procedure definition itself, rather than in the .data or;.bss sections.Newlines:pushad; Save all caller's registerscmp edx,15; Make sure caller didn't ask for more than 15ja .exit; If so, exit without doing anythingmov ecx,EOLs; Put address of EOLs table into ECXmov eax,4; Specify sys_writemov ebx,1; Specify stdoutint 80h; Make the kernel call.exitpopad; Restore all caller's registersret; Go home!EOLsdb 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10;-------------------------------------------------------------------------; PrintLine: Displays the hex dump line string via INT 80h sys_write; UPDATED:4/13/2009; IN: Nothing; RETURNS:Nothing; MODIFIES: Nothing; CALLS:Kernel sys_write; DESCRIPTION:The hex dump line string is displayed to stdout using ;INT 80h sys_write.PrintLine:pushad; Push all GP registersmov eax,4; Specify sys_write callmov ebx,1; Specify File Descriptor 1: Standard outputmov ecx,DumpLin; Pass offset of line stringmov edx,FULLLEN; Pass size of the line stringint 80h; Make kernel call to display line stringpopad; Pop all GP registersret


程序和HexDump2差不多,没有必要再分析。

makefile文件:

hexdump3: hexdump3.o textlib.old -o hexdump3 hexdump3.o textlib.otextlib.o: textlib.asmnasm -f elf -g -F stabs textlib.asmhexdump3.o: hexdump3.asmnasm -f elf -g -F stabs hexdump3.asm

以下是测试结果:

[root@bogon hexdump3]# makenasm -f elf -g -F stabs hexdump3.asmnasm -f elf -g -F stabs textlib.asmld -o hexdump3 hexdump3.o textlib.o[root@bogon hexdump3]# ./hexdump3 123456789012345 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 0A |123456789012345.|


0 0
原创粉丝点击