0

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
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Adam Lee
  • 436
  • 1
  • 14
  • 49
  • Assembly supports it. That's why your code passed the assembler. The crash is at runtime, not assembly time. – Raymond Chen Nov 06 '20 at 21:10
  • @RaymondChen Does byteCount need to be of a certain type in order for it to be supported by Assembly? – Adam Lee Nov 06 '20 at 21:16
  • 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. – Peter Cordes Nov 06 '20 at 21:20

1 Answers1

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:

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847