title: Assembly: Convert hex string into single byte
body: <p>In assembly, say you have a hex string of '0x2f'. How would you convert this into a single byte of the value '0x2f'? </p>
  
  <p>Example (Assumes SI equals the location of your 2-character hex string, and conv_hex2byte does the conversion, returning the result in AL):</p>
  
  <pre><code>jmp    main
  foo    db '2f'
  bar    db 0
  main:
      mov    si, foo
      call    conv_hex2byte
      mov    byte [bar], al
      ; bar should now have a value of '2f'
      ret
  conv_hex2byte:
      ; What would go here?
      ret
  </code></pre>
  
  <p>Edit: I've got this attempt at conv_hex2byte...</p>
  
  <pre><code>conv_hex2byte:
  push    ebx
  push    ecx
  push    edx
  
  ; Clear general registers
  xor eax, eax
  mov bx, .tmp0
  mov ecx, eax
  mov edx, eax
  
  .char:
  lodsb
  mov dl, al
  cmp dl, '0'
  jl  .is_hex
  cmp dl, '9'
  jg  .is_hex
  sub al, '0' ; Make '0' = 0h
  .write_val:
  mov bx, .tmp0
  add bx, cx
  mov [bx], dl
  inc cl
  cmp cl, 2
  jl  .char
  mov ah, byte [.tmp0]
  shl ah, 4
  mov al, byte [.tmp1]
  or  al, ah
  xor ah, ah
  ;call   os_dump_registers
  pop edx
  pop ecx
  pop ebx
  ret
  
  .is_hex:
  cmp dl, 'F'
  jg  .lower
  sub dl, 55 ; Make 'A' = 0ah
  jmp .write_val
  
  .lower:
  sub dl, 87 ; Make 'a' = 0ah
  jmp .write_val
  
  .tmp0   db 0
  .tmp1   db 0
  </code></pre>
  
  <p>For some reason, it produces the wrong number... i.e. </p>
  
  <pre><code>push hex
  call conv_hex2byte
  hex db '20'
  </code></pre>
  
  <p>results in AX equaling <code>0x32</code> rather than <code>0x20</code>.</p>