For example, what is the difference between
cmpl $0x7, 0x8(%rsp)
and
cmpl $0x7, (%rsp)
Also what is the difference between cmp
and cmpl
?
For example, what is the difference between
cmpl $0x7, 0x8(%rsp)
and
cmpl $0x7, (%rsp)
Also what is the difference between cmp
and cmpl
?
A memory operand on x86 in AT&T syntax is generally "offset(base, index, scale)" where offset is a (constant) offset, base is a (base) register, index is an (index) register, and scale is the constant 1, 2, 4 or 8. However, most of these fields can be omitted to get a default value. No offset means an offset of 0. No base means no base regiser. No index and scale means no index register.
In your specific examples, (%rsp)
means %rsp
as the base register, with no offset and no index. 0x8(%rsp)
means %rsp
as the base register and 0x8 (8) as the offset.
Intel describes the instruction mnemonic as CMP
(in Intel 64 and IA-32 Architectures software Developer’s Manual), but there are many forms of the instruction, such as comparing 8-, 16, 32-, or 64-bit numbers, comparing an immediate value with a value in memory, and so on.
Some assemblers use suffixes to distinguish the operand width, using:
b
for byte,w
for word (two bytes in Intel’s use in these architectures),l
for long word (four bytes), andq
for quad word (four words, eight bytes).If one of the operands is a register, the assembler can figure out (at least theoretically; some assemblers might not feature this) the width from it.
For example, cmp $0x7, %rsp
would be a 64-bit compare since %rsp
names a 64-bit register. (%esp
is a 32-bit register, %sp
is a 16-bit register.)
cmpl $0x7, (%rsp)
means a 32-bit compare of the immediate value 0x7
with data in memory at the address contained in the %rsp
register.
Without the l
suffix, the width in this instruction is not known. 0x7
is an immediate value. Unlike C, there is no default type for it.
Similarly, (%rsp)
is a location in memory without an associated type. So the l
is needed. (Note the difference here: cmp $0x7, %rbp
would compare 7 to the value in %rbp
, while cmp $0x7, (%rbp)
would compare 7 to the value in the memory at the address in %rbp
.)
8(%rsp)
means the address resulting from adding 8 to (%rsp)
.
A fuller form is offset(base, index, scale), which represents the address in base (which is a register) plus index (another register) times scale (a constant 1, 2, 4, or 8) plus offset.
This form is used for indexing arrays: Suppose an array starts at address %rax
and has elements 4 bytes wide, and you want the element with the index in %rbx
. Then you an address this element with (%rax, %rbx, 4)
. The additional offset can be added to refer to members within structures within the array or to adjust the base address of the array relative to %rax
.
I believe the answer to your question can be found in this other SO question: The difference between cmpl and cmp