//----------------------------------------------------------------- // dopushal.s // // This program illustrates a useful 'table-lookup' technique // for labeling your numerical output and also for converting // a numerical value to its hexadecimal digit-representation. // // to assemble: $ as dopushal.s -o dopushal.o // and to link: $ ld dopushal.o -o dopushal // // programmer: ALLAN CRUSE // written on: 11 FEB 2007 //----------------------------------------------------------------- .section .data hex: .ascii "0123456789ABCDEF" # table of hex numerals .section .text eax2hex: # # This procedure converts the 32-bit value found in register EAX # into its representation as a string of hexadecimal numerals at # the location in memory whose address is found in register EDI; # values in the CPU's general registers are returned unmodified. # push %eax # save working registers push %ebx push %ecx push %edx push %edi mov $8, %ecx # setup iteration-count nxnyb: rol $4, %eax # next nybble into AL mov %al, %bl # copy nybble into BL and $0xF, %ebx # isolate nybble's bits mov hex(%ebx), %dl # lookup nybble's digit mov %dl, (%edi) # and store it in buffer inc %edi # advance buffer-pointer loop nxnyb # again for next nybble pop %edi # recover saved registers pop %edx pop %ecx pop %ebx pop %eax ret # return control to caller # manifest constants .equ sys_EXIT, 1 # system-call ID-number .equ sys_WRITE, 4 # system-call ID-number .equ dev_STDOUT, 1 # device-file ID-number .section .data names: .ascii " EDI ESI EBP ESP EBX EDX ECX EAX" # name-table nelts: .int (. - names)/4 # count of table-elements buf: .ascii " nnn=xxxxxxxx \r\n" # buffer for display info len: .int . - buf # buffer's length (bytes) .section .text _start: # execute the 'pushal' instruction pushal # push general registers # now display the eight general-purpose register-values xor %esi, %esi # initialize array-index nxelt: # put element-name in the output-buffer mov names(, %esi, 4), %eax # get element's name mov %eax, buf # put name into buffer # put element-value in the output-buffer mov (%esp, %esi, 4), %eax # get element's value lea buf+5, %edi # point to value field call eax2hex # convert number to hex # draw buffer's contents on the screen mov $sys_WRITE, %eax # ID-number for 'write' mov $dev_STDOUT, %ebx # ID-number for display lea buf, %ecx # address of the string mov len, %edx # length of the string int $0x80 # invoke kernel service # increment array-index for next loop-iteration inc %esi # increment array-index cmp nelts, %esi # check: beyond bounds? jb nxelt # no, show next element # terminate this program mov $sys_EXIT, %eax # ID-number for 'exit' xor %ebx, %ebx # use zero as exit-code int $0x80 # invoke kernel service .global _start # make entry-point public .end # no more to be assembled