assemblyx86-64attzero-extension

Moving a value of a lesser size into a register


I have stored a one-byte value of 8 and I'd like to move that into the rax register. I'm currently doing this with movzx to zero-extend the byte:

.globl main
main:
    push %rbp
    mov %rsp, %rbp
    movb $8, -1(%rbp)
    movzx -1(%rbp), %rax <-- here
    ...

How does the movzx instruction 'know' that the value at -1(%rbp) is only one byte long? From here is says, if I'm reading it properly, that it can work on both a byte and a word, but how would it know? For example, if I added a two-byte value at -2(%rbp) how would it know to grab the two-byte value? Is there another instruction where I can just grab a one or two or four byte value at an address and insert it into a 64 bit register?

I suppose another way to do it would be to first zero-out the register and then add it to the 8-bit (or however many bits) component, such as:

mov $0, %rax
mov -1(%rbp), %al

Is there one way that is more preferred than another way?


Solution

  • How does the movzx instruction 'know' that the value at -1(%rbp) is only one byte long?

    There are two (or even three) instructions:

    movzxb (-1(%rbp) is one byte long) and movzxw (-1(%rbp) is one 16-bit word long).

    My assembler interprets movzx as movzxb; however, you should not rely on that!

    Better use the instruction name including the source size (movzxb or movzxw) to ensure that the assembler uses the correct instruction.