0

I'm trying to do an assignment for my assembly class, and the teacher's example has the line

movl (%eax),%ebx

My code uses this exact same line, but whenever gdb reaches it, i have a seg fault. I don't understand why. Please help me. This is the whole code, running via QEMU on 32 bit Linux.

.text
.byte 12, 0x12, 012
.word 34, 0x34, 034
L1:
.long 23, 0x23, 023
.global _start
_start:
  # do not change, remove or add anything other than specifying the underscores
  movl $0x1700121C,%eax  #hex for 385880604
  movl (%eax),%ebx       #moving contents of eax into ebx, long to long
  movw 0x17,%bx          #attemtping to move via memory location (probably buggy)
  movb $0x12,%bh

  # at this point, %ebx should have the value of 385880604
checkHere:

  movl $1,%eax
  movl $0,%ebx
  int  $0x80

Please help. Thanks for your time.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 1
    `movl (%eax),%ebx` treats whatever is in `%eax` as a pointer and retrieves the 32-bit value at that address and places it in `%ebx`. If `0x1700121C` is not a valid pointer (at least is doesn't appear to be), it will segfault. – Michael Petch Mar 03 '16 at 20:43
  • But we were given the code in the line above as movl $____,%eax Doesn't that mean it has to be a constant? – Angela English Mar 03 '16 at 21:16
  • Yes, the `$` means that a constant will follow, but usually when it comes to pointers it will be the name of a label. So it would be `$label` where `label` is the name of a label you want the address (pointer) of. – Michael Petch Mar 03 '16 at 21:20
  • So should I replace 0x1700121C with L1, you think? – Angela English Mar 03 '16 at 21:59
  • I don't have the full question, so knowing whether L1 is correct is not something I can answer, but `$L1` would be valid syntax. If we had the complete question, it would be easier to answer. – Michael Petch Mar 03 '16 at 22:04

2 Answers2

0

"movl $0x1700121C,%eax #hex for 385880604" needs to reference a label/a memory address.

0

The goal of this assignment is to end up with a given value (0x1700121C) filling a certain register (ebx).

When a program is run, it may be placed just about anywhere in memory, for both the program and the memory it allocates (e.g. for variables).

You are telling it to look at an absolute address, which is not what you want. You don't actually know where your program and its allocated bytes of RAM ended up. You want to use relative addresses here. (Under the hood, some information in the header of the executable helps this happen, if you're curious)

But how do you get relative addresses? You can take advantage of L1. You don't know its exact numeric address, but you do know it starts wherever .long 23 starts. You can do math on L1 to get relative addresses. Since there are some bytes before wherever in memory L1 points to, you'll need to subtract.

.words are 2 bytes and there are 3 of them, plus there's 3 bytes before that, so L1 - 9 gets you to the first byte of this data.

  • It's not actually position-independent machine code. It *is* position-independent source code, though, so you don't have to modify constants when changing the code: using symbolic labels lets the linker fill in the right absolute address. Executables specify where they are to be mapped into virtual memory. Dynamic libraries do need to use position-independent code (`gcc -fPIC`), which is quite a burden in 32bit mode. 64bit mode added RIP-relative addressing, which makes PIC cheap. (See [this guide I wrote about addressing modes](http://stackoverflow.com/a/34058400/224132)) – Peter Cordes Mar 04 '16 at 02:30