I am trying to read a section of memory, byte by byte, starting from the memory address stored in the EAX register. I push the current byte to the EBX register. However, when I execute the following line of code (advanced indexing mode):
movb byteCount(%eax), %ebx
I get the following error:
Program received signal SIGSEGV, Segmentation fault.
It seems that Assembly doesn't supporting using a label in advanced indexing. How would I go about emulating this same action without using a label or register before (%eax)? Below is the data section:
.data
str:
.string "abcdefg"
byteCount:
.int 1
In that context, byteCount
is the label address, not the dword that happens to be in memory there. You need to load all runtime-variable things into registers to use them in addressing modes; x86 doesn't do memory-indirect addressing.
mov byteCount, %edx # dword load
movzbl (%eax, %edx), %ebx # zero-extending byte load
Or of course you could use add byteCount, %eax
and deref (%eax)
. Or better, you could keep byteCount
in a register in the first place, where you need it anyway. That's what registers are for. In x86 assembly, when should I use global variables instead of local variables? (usually you shouldn't).
movb
into EBX is an error (operand-size mismatch), so certainly that's not what you actually ran. But that would access a byte at bytecount[ (uintptr_t)eax ]
. If you'd used just mov
, it would be a dword load.
But regardless, the sum of two addresses is rarely a valid address, so it segfaults. Your debugger should have told you the faulting address so you could see it was far from str
.
Related: