//---------------------------------------------------------------- // hex2eax.s // // This file defines a procedure which can be called from a // separate assembly language program that wants to convert // a string of hexadecimal digits into the integer which it // represents -- provided that this can be done without any // overflow. The address of the source-string is passed in // register ESI, and the value is returned in register EAX. // The carry-flag is clear unless EAX overflows. The other // CPU registers (except EAX and EFLAGS) will be preserved. // // assemble using: $ hex2eax.s -o hex2eax.o // // programmer: ALLAN CRUSE // written on: 13 FEB 2006 //---------------------------------------------------------------- .section .text hex2eax: pushal # preserve CPU registers # initialize the function's return-value in register EAX xorl %eax, %eax # clear the accumulator nxchr: # get the next character-value as a 32-bit value in EDX xorl %edx, %edx # clear the data-register movb (%esi), %dl # next character into DL incl %esi # advance source pointer # see if the character lies between '0' and '9' cmpb $'0', %dl # character preceeds '0'? jb ckuc # yes, not within range cmpb $'9', %dl # character follows '9'? ja ckuc # yes, not within range subb $'0', %dl # else convert to binary jmp isok # process the new nybble ckuc: # see if the character lies between 'A' and 'F' cmpb $'A', %dl # character preceeds 'A'? jb cklc # yes, not within range cmpb $'F', %dl # character follows 'F'? ja cklc # yes, not within range subb $'A', %dl # else convert to binary addb $10, %dl # and add hex adjustment jmp isok # process the new nybble cklc: # see if the character lies between 'a' and 'f' cmpb $'a', %dl # character preceeds 'a'? jb inval # yes, not within range cmpb $'f', %dl # character follows 'f'? ja inval # yes, not within range subb $'a', %dl # else convert to binary addb $10, %dl # and add hex ajustment jmp isok # process the new nybble isok: # ok, we multiply prior total by 16, then add new digit shll $4, %eax # accumulator times 16 addl %edx, %eax # gets new nybble added jc fini # overflow? return CF=1 jmp nxchr # else check next char inval: clc # clear the carry-flag fini: movl %eax, 28(%esp) # overwrite the EAX-value popal # restore saved registers ret # return control to caller .global hex2eax # make entry-point visible .end # nothing more to assemble