5
\$\begingroup\$

I try to learn amd64 assembler. This is the first thing I tried. This piece of assembly should replicate the functionality of the following piece of C code, which turns a binary sha-256 hash into a human readable form.

assembly code

1:  .ascii "0123456789abcdef"
    .global show_hash
show_hash:
    .type show_hash @function
    .func show_hash
    mov $32,%ecx
    .p2align 2
0:  xor %eax,%eax
    lodsb
    mov %eax,%edx
    shr $4,%al
    and $15,%dl
    mov 1b(%rax),%al
    mov 1b(%rdx),%dl
    mov %bl,%ah
    stosw
    dec %ecx
    jnz 0b
    mov %cl,(%rdi)
    ret
    .endfunc

C code

void show_hash(char *dst, unsigned char *src) {
  static const char *lookup = "0123456789abcdef";
  char lo, hi, byte;
  int i = 32;

  do {
    byte = *src++;
    hi = lookup[byte >> 4];
    lo = lookup[byte & 0xf];
    *dst++ = hi;
    *dst++ = lo;
  } while (i--);
}

Am I doing it right? I tried to move the lookup table (label 1) into .section rodata, but all references to it were changed to 0 in the linked program, so I put it into the text section for now.

\$\endgroup\$
7
  • \$\begingroup\$ I don't think you can access data unless it's in the data segment. \$\endgroup\$
    – Hawken
    Commented Oct 22, 2012 at 23:42
  • \$\begingroup\$ @Hawken How do you come to this conclusion? \$\endgroup\$
    – FUZxxl
    Commented Oct 23, 2012 at 5:02
  • \$\begingroup\$ all memory is referenced using the segment specified by %ds or if it's on the stack, %ss. Unless you have personally set the segment register, mov %cs,%ds, or your assembler is adding a custom segment offset, you can't read from outside .data. I don't know if modern OSs allow you to read from .text at all even if you did. \$\endgroup\$
    – Hawken
    Commented Oct 26, 2012 at 20:43
  • \$\begingroup\$ @Hawken You see that this code is written for x86-64 linux which uses a flat memory modell? All segment registers except %fs and %gs which serve a special purpose are set to zero. \$\endgroup\$
    – FUZxxl
    Commented Oct 26, 2012 at 20:48
  • \$\begingroup\$ Hmm, I did not know that. wiki.osdev.org/X86-64 contains information on this for anyone else who did not know. \$\endgroup\$
    – Hawken
    Commented Oct 26, 2012 at 21:43

1 Answer 1

3
\$\begingroup\$

I'm not sure whether it's correct:

  • If show_hash uses cdecl calling conventions you should preserve registers like %bl, and read the input parameter values from the stack into esi and edi.
    (see section "3.2.3 Parameter Passing" of the Application Binary Interface: parameters are conveniently passed in the rdi and rsi registers)
  • I don't understand the syntax of mov 1b(%rax),%al: is it reading from the lookup array defined at label 1:? On re-reading, I think it is; however that will only work if the most-significant bytes of rax and rdx are all zero; perhaps you should initialize them as you did using xor %eax,%eax
    (apparently xor %eax,%eax will clear the whole of %rax)
  • You're using stosw which writes two bytes (two ASCII characters) a time; but %ah contains a value from %bl, and %bl wasn't previously initialized? I think that statement should have been mov %dl,%ah not mov %bl,%ah; or perhaps you could have done mov 1b(%rdx),%ah directly.
  • The function ends with mov %cl,(%rdi) to null-terminate the string; that is clever but could use a comment (it took me a bit to figure out). Most of the questions either have good comments, or answer which say that they should have good comments.
\$\endgroup\$
3
  • \$\begingroup\$ xor %eax,%eax implicitly zeroes out the upper 32 bits of %rax as well. Second, this is x86_64 assembly on Linux. The calling convention is different; the first couple of arguments are actually passed in registers. I think I accidentially switched %dl with %bl, but I'm not very sury. \$\endgroup\$
    – FUZxxl
    Commented Mar 6, 2014 at 20:12
  • \$\begingroup\$ I asked this question almost a year ago; I'm not really sure about most parts anymore. \$\endgroup\$
    – FUZxxl
    Commented Mar 6, 2014 at 20:15
  • \$\begingroup\$ In that case the only error I see is the typo involving %bl instead of %dl. \$\endgroup\$
    – ChrisW
    Commented Mar 6, 2014 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.