1

I'm coding ASM, and I really don't understand about the rules of mov, so

    mov rax, 100 ; it means that the number 100 is in rax?
    mov rax, a   ; it means that the value of a is in rax? or is the memory direction?
    mov rax, [a] ; it means the value of a? or what?
    mov [a], rax ; the direction of memori in a change to rax?
    mov rax, rbx ; rbx is now rax?

Sorry if my question is dumb but I'm really confuse... thank you

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • The meaning of `mov rax, a` depends on whether you're using NASM or MASM syntax. (Address or value at that address). Either way, though, this is Intel syntax so the destination is always the left-most operand, so your last comment is wrong. (Or unclear phrasing to describe `rax = rbx`). Any tutorial should explain these basics, though, so probably you should just keep reading. Some links to tutorials can be found in https://stackoverflow.com/tags/x86/info – Peter Cordes Oct 03 '21 at 21:37
  • `mov left, right` always means `left = right`. The only question is what `a` vs. `[a]` means depending on the assembler. (Assuming register names and immediate constants are obvious.) – Peter Cordes Oct 03 '21 at 21:42

1 Answers1

2

Since we have, mov rax, 100 as valid, we know it's Intel syntax. Proceeding on and assuming a is a label rather than a macro or equ resulting in a constant:

mov rax, 100 ; Always means put constant 100 in rax
mov rax, a   ; Either means put the address of a in rax,
             ; or put a in rax depending on which assembler.
             ; For nasm it's always the address of a.
mov rax, [a] ; Always means the 8 byte value stored at a
             ; for offsets above 2GB, target register must be al, ax, eax, or rax
mov [a], rax ; Put the value of rax in the value stored at a
mov rax, rbx ; Put the value of rbx in rax (no memory access)
mov rax, [rbx] ; Put the value stored where rbx points into rax

I added the last one for completeness. Not doing the math in [] operations here.

However you rarely want to load absolute addresses; you usually want rip-relative, you should normally write the following (NASM syntax):

lea rax, [rel a] ; put address of a into rax
mov rax, [rel a] ; put value at a into rax
Joshua
  • 40,822
  • 8
  • 72
  • 132
  • x86-64 allows `mov r64, imm64` for any register. You're probably thinking of the `mov al/ax/eax/rax, moffs` forms that load or store with a 64-bit absolute address, which do only exist for the accumulator (4 opcodes, not 32). https://www.felixcloutier.com/x86/mov. – Peter Cordes Oct 03 '21 at 21:48
  • 1
    In MASM where `mov rax, a` is a load, `a` will use a RIP-relative addressing mode so you can load into any register. (In GAS `.intel_syntax noprefix`, bare `a` is a memory operand with a normal `[disp32]` addressing mode, which might not link; `movabs` for 64-bit absolute, `[a + rip]` for RIP-relative) – Peter Cordes Oct 03 '21 at 21:50
  • But anyway, in NASM you basically never want to do `mov rax, a` to [get a static address into a register](https://stackoverflow.com/questions/57212012/how-to-load-address-of-function-or-label-into-register). Either do `lea rax, [rel a]` or as an optimization in executables that are known to be linked into the low 32 bits of address space (like non-PIE on Linux), `mov eax, a`. Still, `mov rax, a` does work inefficiently, and Linux dynamic linking does support runtime fixups (text relocations) on 64-bit absolutes in shared objects such as PIE executables. – Peter Cordes Oct 03 '21 at 21:52
  • @PeterCordes: Why would you want to not load an 8 byte data variable if your code is guaranteed to be loaded below 2GB because of the way you linked it? – Joshua Oct 03 '21 at 21:53
  • 1
    My last comment is talking about NASM, where `mov rax,a` puts the address into the register. `mov eax, a` is 5 bytes of machine code, so achieves the same result more efficiently than `lea rax, [rel a]` (7 bytes). I only mentioned it as an example of when it does still make sense to use `mov` with an absolute address as an immediate in x86-64, since that's what that instruction is already doing (with a 64-bit immediate) if assembled by NASM. See the link I edited into my previous comment while you were typing. – Peter Cordes Oct 03 '21 at 21:56
  • I also remember the one time I needed to write x64 assembly and wanted RIP-relative addressing I ran into some kind of assembly trouble, and did `ORG 0` followed by stuffing my base address into `rbp` and proceeding to write [rbp + label] everywhere. – Joshua Oct 03 '21 at 21:56
  • That sounds unusual. A working toolchain of assembler + linker does let you use RIP-relative addressing normally. Of course you can't do `mov eax, [label + rax]` or something; RIP-relative *only* works without other registers so `[label + rbp]` has to user `[rbp + disp32]`. (And that means you can't use that addressing mode with labels in PIE executables, [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427)) – Peter Cordes Oct 03 '21 at 21:59
  • In your answer, I guess you're assuming NASM without `default rel` for `mov rax, [a]` (or GAS `.intel_syntax`)? Yes that's true that it only works for RAX, but really you should use `default rel`. For MASM, `[a]` or `a` will pick a RIP-relative addressing mode and work when linked into an executable or library where the data is within +-2 GiB of the code. – Peter Cordes Oct 03 '21 at 22:02
  • "RIP-relative only works without other registers" ohhh that was it. I really needed variable offset into an array whose start was marked in a label. – Joshua Oct 03 '21 at 22:03
  • 1
    The `[rel a]` syntax is specific to NASM. GAS uses `[RIP + a]` ([How do RIP-relative variable references like "\[RIP + \_a\]" in x86-64 GAS Intel-syntax work?](https://stackoverflow.com/q/54745872)), MASM doesn't use anything. This is why I didn't answer this question that didn't specify a language, only Intel syntax in general. Writing a correct answer requires getting into more detail than a total beginner who's not sure about `mov rax, 100` is probably ready to deal with. – Peter Cordes Oct 03 '21 at 22:04
  • Ah yeah, to index a static array in PIE/PIC code, x86-64 needs to LEA the array base into a register and use `[reg + reg*scale]` addressing. [Mach-O 64-bit format does not support 32-bit absolute addresses. NASM Accessing Array](https://stackoverflow.com/q/47300844) – Peter Cordes Oct 03 '21 at 22:06