2

With ARM I can access a memory location like this:

LDR r0, [r1, #4]!

Meaning I want to load the value pointed to by r1, with an offset of 4 bytes, and the ! means that I want the value of r1 to be updated after this instruction with the new value (i.e., +4).

Is there an equivalent on x86 (AT&T syntax if possible)? For instance:

movl 4(%ebx), %eax

This will load the value pointed by %ebx with an offset of 4 bytes into %eax. How do I update the value of %ebx after the load though?

Thanks.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
Daniel Scocco
  • 7,036
  • 13
  • 51
  • 78
  • I think you mean `4(%ebx)`, right? Aside from that, I don't know if intel has auto-incrementing addressing modes. I'll take a quick look at the docs... – Carl Norum Jul 02 '13 at 23:32
  • Ain't 4(%ebx) equivalent to (%ebx,4)? – Daniel Scocco Jul 02 '13 at 23:33
  • My assembler won't take it: `example.s:3:scale factor of 4 without an index register`. – Carl Norum Jul 02 '13 at 23:35
  • Gotcha. I think that inside the parenthesis you may only include another register as offset then. Thanks – Daniel Scocco Jul 02 '13 at 23:37
  • Then you'd have an index register, yes. The multiplication by 1 is implicit, or you can add the 2 or 4 yourself if you want something fancier. – Carl Norum Jul 02 '13 at 23:37
  • 2
    @DanielS: Numbers inside the parenthesis for AT&T Syntax x86 assembly mean a "scale factor"; you say `offset(%basereg, %indexreg, scale)` meaning the address to use is `offeset + basereg + scale * indexreg`. The only options for the scale value are `0/1/2/4/8`. The way addresses are written is the weirdest bit of the AT&T Syntax; in Intel's style, you actually write `[ basereg + scale * indexreg + offset ]`. – FrankH. Jul 03 '13 at 08:14
  • @FrankH, thanks, makes more sense now. – Daniel Scocco Jul 03 '13 at 13:35

1 Answers1

5

I think the instruction you're looking for is LODSD which means "load DWORD from string". You don't get to pick the registers though: The pointer is in ESI and the destination register is EAX.

After the byte, word, or doubleword is transferred from the memory location into the AL, AX, or EAX register, the (E)SI register is incremented or decremented automati- cally according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)SI register is incremented; if the DF flag is 1, the ESI register is decre- mented.) The (E)SI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.

Sorry, I've got Intex syntax ingrained in my head right now. Assuming flat 32-bit protected mode:

mov   esi, _source_data_       ; ESI points to source data
cld                            ; Clear the direction flag
                               ; (ESI will increment)
lodsd                          ; Essentially   mov eax, [ds:esi]
                               ;               add esi, 4
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 3
    Now while this instruction exists ... the sequence `mov (%esi),%eax; lea 4(%esi),%esi` might be faster. The so-called _string instructions_ have rather high instruction latencies, and they're tied to using registers `%edi` (for stores) and `%esi` (for loads) _only_. No, this is definitely _not as flexible_ as ARM's generic post/pre-in/decrement addressing. – FrankH. Jul 03 '13 at 08:09