x86汇编:如何将数据标签的起始地址压入栈中?
Hey there! Let's figure out why you're hitting that segmentation fault when pushing data_set's address to the stack, and how to fix it.
First: Why the Segmentation Fault?
When you run pushl data_set, you are correctly pushing the starting address of your data_set (from the .data section) onto the stack. The segfault almost always comes from how you're accessing that address later, not the push itself. Let's break down the common mistakes and fixes.
1. Fix Your Address Access Logic
The key mistake here is usually forgetting to use indirect addressing when accessing the data via the address stored on the stack. Let's compare wrong and right approaches:
❌ Wrong (Causes Segfault)
If you treat the address pulled from the stack as a raw value instead of a pointer, you'll end up accessing invalid memory:
pushl data_set popl %eax movl %eax, %ebx ; %eax holds the *address* of data_set, not the value at that address ; If you try to use %ebx as a value here, you're working with a memory address (like 0x80490a0) ; instead of the actual data (2, 5, etc.)
✅ Correct (Works as Expected)
You need to use parentheses around the register holding the address to perform indirect access (i.e., "go to this address and get the value stored there"):
.section .data data_set: .long 2,5,33,54,2,76,4,37,43,223,98,70,255 .section .text .globl _start _start: pushl data_set ; Push the address of data_set onto the stack popl %eax ; Pull the address into %eax movl (%eax), %ebx ; Indirect access: grab the first value (2) from the address in %eax ; To access the second element (5), increment the address by 4 bytes (size of a long): addl $4, %eax movl (%eax), %ecx ; %ecx now holds 5 ; Clean exit for Linux movl $1, %eax int $0x80
2. Verify Memory Permissions & Compilation
If the above fix doesn't work, double-check your build process and section permissions:
- Use standard tools to compile/link (for Linux):
as -o your_program.o your_program.s ld -o your_program your_program.o - The
.datasection is read-write by default, but if your linker script or flags accidentally marked it as read-only, you'd get a segfault on write operations. Useobjdumpto check permissions:
Look for theobjdump -h your_program.o | grep .dataFLAGScolumn—you should seeRW(read-write).
3. Confirm the Address is Valid
You can verify the exact address of data_set with objdump to ensure you're pushing a valid memory location:
objdump -x your_program | grep data_set
This will show the virtual address of data_set after linking—confirm it falls within the .data section's range.
内容的提问来源于stack exchange,提问作者talz

