Statistics

Members: 1925
News: 293
Web Links: 1
Visitors: 3823169

Who's Online

We have 1 guest online
Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home arrow Articles - Programming arrow Assembly arrow Convert ASCII hex to binary in 6 bytes
Convert ASCII hex to binary in 6 bytes
User Rating: / 1
PoorBest 
Written by Mammon   


The Challenge
-------------
Write a routine for converting ASCII hex to binary in 6 bytes.

The Solution

Well, actually, I cheated: I found the following text on the internet a few months ago and decided to see if I could beat it: ===================================================================-Asc2hex.txt An efficient algorithm for converting ASCII hex to binary Ken Sykes (72177,141)
David Ogle (75676,2612)

There is a well-known algorithm for converting a binary number between one and fifteen to its equivalent hex form in ASCII that only requires four assembly language instructions. Assuming that the number to convert is in AL, the following sequence performs the conversion:

        add    al,90h
daa
adc    al,40h
daa

This instruction sequence is, as far as we know, the shortest (16 cycles) self-contained routine to convert a binary number to hex. Inspired by this code and the fact that a similar routine to convert ASCII hex to binary would be useful, we came up with two algorithms that convert an ASCII hex digit to binary in five assembly instructions or less.

The first algorithm takes advantage of an undocumented feature of the 8088. The AAM instruction (Ascii Adjust for Multiply) divides AL by 10, placing the remainder in AL and the quotient in AH. The opcode for AAM is: 0D4h,0Ah. It's no coincidence that the second byte is 10 - the 8088 uses the second byte of the opcode as the divisor! The same rule applies to the AAD (Ascii Adjust for Division) instruction. With this in mind, a conversion routine goes as follows (assuming the ASCII digit is in AL and in the range '0..9,A..F'):

        sub    al,'0'
aam    16
aad    9

The only problem is the Microsoft Assembler does not accept this form. By placing the opcodes in data statements, however, the following code will assemble properly:

        sub    al,'0'
db    0D4h,10h
db    0D5h,09h

At three instructions and six bytes of code space, We are reasonably sure this is the shortest self-contained sequence to perform the conversion. The only drawbacks are the use of non-standard opcodes and the execution time (147 cycles!). The second algorithm, loosely-based on this one, relieves these restrictions.

The second algorithm makes exclusive use of fast instructions to perform the conversion (again, AL holds the digit to convert):

        add    al,40h
cbw
and    ah,09h
add    al,ah
and    al,0Fh

While two additional instructions are required, the routine executes in 17 cycles. We are reasonably sure this is the fastest-executing selfcontained code to perform the conversion. It has the added benefit of handling the ASCII values 'a'..'f'.

These algorithms will hopefully trim down the execution times of your programs, and we welcome any suggestions or improvements on our code.

Happy Hacking!
===========================================================================-EOF

Sadly, I was unable to come up with a smaller version, or a faster one. Tinara posted a similar solution to the APJ Message Board:

      SUB AL, 30h
AAM 10h         ; db D4h, 10h
AAD 09h         ; db D5h, 09h

...so he gets kudos for uncovering by work what I managed by stealth. As for next issue, I haven't had time to prepare a challenge, but I'm sure one will crop up in the next month or so.

Next Issue Challenge

None so far... submissions welcome.