-3

Giving the following assembly code I know that .data grows towards higher addresses so after running the code the memory looks something like:

-
-
-
-
-
-
-
- (var3 here and up)
-
-
-
- (var2 here and up)
-
-
-
- (var1 here and up)

So when they ask what will be saved in register rsp at the end why the blue option is the correct one?

enter image description here

Here is how I tried to solve it:

  • In first line we are trying to save the value of var3 in the register, the value of var3 is the value of var2 which is -1, in the second line we add 6 to it so in total we get 5.

Please Note, In previous question I was told that label or variable with no $ before it means its value in memory (data) where adding $ means its address in memory.

Dan
  • 99
  • 6
  • 1
    Do not post pictures of test! [Edit] your question and replace the picture with the test that is in it. – fuz Oct 07 '21 at 18:53
  • Downvoted because you posted a picture of text. Replace the picture and I'll go ahead and remove the downvote. – fuz Oct 07 '21 at 19:00
  • @fuz shouldn't I wait for permission from my teacher? I know it's strange but he allowed passing pictures but not copying parts... – Dan Oct 07 '21 at 19:01
  • 1
    If you are not permitted to publish the picture under the terms of the MIT license (which includes the right to copy parts), you should not post it here at all. – fuz Oct 07 '21 at 19:58

1 Answers1

1

The value of var3 is var2, i.e. the address of var2. The .int, .quad, ... directives always store the addresses of their operands into memory. Which is also why you have .int 0 instead of .int $0. So your reasoning is wrong. Also you forgot to account for the effect of the pushq instruction on the contents of the rsp register (pushing a qword decreases rsp by 8).

What actually happens:

mov var3, %rbx

The content of var3 is moved into rbx. var3 holds the address of var2.

lea 6(%rbx), %rsp

The stack pointer is loaded with rbx + 6. As rbx holds var2, this is now var2+6.

pushq $0xffc8

Something is stored on the stack, decreasing rsp by 8. rsp now holds var2-2.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • "i.e. the address of var2" not what you told me here: https://stackoverflow.com/questions/69484696/labels-and-variables-in-assembly you said 5 is identical to 2.... – Dan Oct 07 '21 at 19:02
  • 2) What if I want to save value of var2 in var3 how can I do that? (in .data section) – Dan Oct 07 '21 at 19:08
  • @Dan It is exactly what I told you. In both cases you have a memory operand. Memory operands access memory at the address given in the operand. There are no double indirect addressing modes in x86 and adding extra parentheses does not change anything. So both `mov var,%eax` and `mov (var),%eax` load 4 bytes from `var` into `eax`. – fuz Oct 07 '21 at 19:10
  • 1
    @Dan To save the value of `var2` into `var3` you need to first load from `var2` and then store into `var3`, e.g. by doing `mov var2, %eax; movq %rax, var3` (note the implicit zero extension to deal with the different variable sizes). – fuz Oct 07 '21 at 19:11
  • I meant doing so in one command (replacing current definition)... – Dan Oct 07 '21 at 19:26
  • You are contradicting yourself again, you just said mov var,%eax without $ loads bytes so why var above loads address and not bytes. This is a clear contradiction to what you just wrote here and there... – Dan Oct 07 '21 at 19:27
  • @Dan: I don't see any contradiction. The qword at `var3` has value = address of var2, because that's what `.qword var2` emits into the output file, like fuz said in the first line of this answer. That assembler directive has to work even for symbols from another file, so if you're thinking that should copy 8 bytes from after that symbol, no, that's not how it works. You can think of symbol-names always being addresses, but *instructions* like `mov` implicitly dereferencing unless there's a `$`, or for registers. IDK if that's helpful because it's equally arbitrary. – Peter Cordes Oct 07 '21 at 19:52
  • @Dan: But anyway, instructions deref at run-time, and there's no way for anything to ever dereference at assemble-time. I'm just assuming that you think the qword at `var3` should be holding `0xffffffff` twice, once copied from var2 and the 2nd copied from the first copy? The fact that they're different sizes should help see why your interpretation would be a super weird design. Only a few assemblers (like MASM) have sizes associated with labels, AT&T syntax is not like that. – Peter Cordes Oct 07 '21 at 19:57
  • @Dan: It might help to try it yourself and look at the resulting assembler listing that shows memory contents. This is all valid AT&T syntax you can assemble with `as -o foo.o foo.s` or `gcc -c foo.s`. And if you tried using `.qword $var2`, you'll see that it treats the `$` as part of the symbol name. – Peter Cordes Oct 07 '21 at 19:58
  • 1
    @Dan There is no single instruction to copy the contents of one variable into another and neither is it possible to define a variable to be initialised with the contents of another variable (except perhaps with copy relocations, but that's very esoteric). – fuz Oct 07 '21 at 20:00
  • @Dan As for the contradiction, there is none. It's just a misunderstanding of addressing modes vs. assembler directives. Addressing modes apply to instructions, not assembler directives. For assembler directives, naming a symbol always refers to its address. It is impossible to have an assembler directive access memory because the process does not exist yet when the assembler runs. You need to get used to that. – fuz Oct 07 '21 at 20:04
  • May [section 4.7](https://www.plantation-productions.com/Webster/www.artofasm.com/DOS/ch04/CH04-3.html) helps understanding. Movement of data by CPU involves a `register`, either in the source...or in the destination... or both. – Nalin Ranjan Oct 08 '21 at 06:27
  • 1
    @NalinRanjan Not necessarily. For example, `mov $0, var1` is a valid instruction and neither source nor destination is a register. – fuz Oct 08 '21 at 07:57