Jontahan Jontahan - 5 months ago 32
C Question

Assembly instruction addl using byte instead of long

I am at the moment studying the assembly code compiled from simple c programs using objdump, but this confuses me:

4004f1: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp)
4004f8: 83 45 fc 05 addl $0x5,-0x4(%rbp)

Doesn't the 'l' prefix in the instructions stand for long, for the movl it looks fine, but the addl seems to use a single byte for the operand, why is this?


Many instructions that operate on immediates can either have an 8 bit immediate or a 32 bit immediate (mov r/m32,i32 notably does not). The purpose of this design is likely to reduce code size. However, the immediate is implicitly sign-expanded to 32 bit. In the case of add, opcode 83 /0 is add with an 8 bit immediate, opcode 81 /0 is add with a 32 bit immediate. Your assembler should automatically choose the shortest encoding. You can assemble this little snippet and then disassemble the result to observe the difference:

.byte 0x83,0xc0,0x00 # addl $0,%eax with an 8 bit immediate
.byte 0x81,0xc0,0x00,0x00,0x00,0x00 # addl $0,%eax with a 32 bit immediate