talz
talz

Reputation: 1200

Assembly, x86: How to push a label to the stack?

given the data:

.section data
data_set:
.long 2,5,33,54,2,76,4,37,43,223,98,70,255

how do I push the start address of the data (and not the value in that address) to the stack?

I tried this:

pushl data_set

which eventually (after trying to access the data in this address) resulted in a segfault.

Upvotes: 1

Views: 3246

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 364248

In AT&T syntax, to use an address as an immediate operand to an instruction, use $label.

You want pushl $data_set for the push imm32 instruction., like you would push $123.

pushl data_set would push a dword of data loaded from the address data_set, i.e.
push m32.


Conceptually, AT&T syntax treats everything as a potential address. So label is an address, and so is 0x123. So add 0x123, %eax loads from the address 0x123, and add label, %eax loads from the address label. When you want a number as an immediate operand, you use add $0x123, %eax. Using a symbol address as an immediate operand works identically.

Either way, the address is encoded into the instruction, it's just a question of whether it's as an immediate or as a displacement in an addressing mode. This is why you use
add $(foo - bar), %eax to add the distance between two symbols, instead of
add $foo-$bar, %eax (which would look for a symbol called $bar, i.e. the $ is part of the symbol name). The $ applies to the whole operand, not to symbol / label names. Related: more about assemble-time math in GAS

In other contexts, e.g. as an operand to .long or .quad, there's no immediate vs. memory operand issue, so you just write dataptr: .long data_set to emit 4 bytes of data holding the address of data_set, like you'd get from C static int *dataptr = data_set;


You could have checked on the syntax by looking at C compiler output for

void ext(int*);
static int data[] = {1,2,3};
void foo() {
    ext(data);
}

to get the C compiler to emit code passing a symbol address to a function. I put this on the Godbolt compiler explorer, where it does indeed use pushl $data.

Upvotes: 7

Related Questions