1

This is a program in Assembler x64 GNU syntax

    .global main
    .text
main: 
    xor  %rax, %rax
    mov  %rax, %rbx

.L1:
    add  $1, %rbx
    add  %rbx, %rax
    cmp  $10, %rbx
    jne  .L1
    ret

I did the loop manually and I found out that when the loop terminates hit the return function (ret), the rbx = 10 and rax = 45, but I do not understand how they go back to main function, and what happens when they go back there?

fuz
  • 88,405
  • 25
  • 200
  • 352
Dan
  • 139
  • 1
  • 8
  • 3
    The x86 ISA doesn't per se have the concept of a return value. How a return value is returned (if at all) is just a convention, though usually, whatever is in `rax` is used as the return value. – fuz Nov 20 '17 at 14:00
  • So basically in the end rax=45 and rbx=10 and that's it, right? – Dan Nov 20 '17 at 14:01
  • 2
    Yes. Also note that the standard calling convention says `rbx` is a callee-saved register so you should really preserve its value. – Jester Nov 20 '17 at 14:06
  • @Dan Exactly. Everything else depends on the calling convention. Though, usually, `rax` contains the return value and the return value of `main` is used as the process' exit status. – fuz Nov 20 '17 at 14:11
  • 2
    to clear rax use `xor %eax, %eax`. [`xor %rax, %rax` waste a byte](https://stackoverflow.com/a/33668295/995714) – phuclv Nov 20 '17 at 14:21
  • @LưuVĩnhPhúc But we have to use x64 and eax is x86, so this is the reason why :) – Dan Nov 20 '17 at 14:24
  • 2
    @Dan please read the link above, it does clear the whole 64-bit register. [Almost all 32-bit instructions clear the top 32 bits in x86_64](https://stackoverflow.com/q/11177137/995714) – phuclv Nov 20 '17 at 14:26
  • @LưuVĩnhPhúc: It's not *almost*, unless you're counting instructions like `test` or stores to memory that don't write any registers. There's no way to write a 32-bit register that doesn't zero-extend into the full 64-bit register. I should probably retitle that question. – Peter Cordes Nov 21 '17 at 23:35

1 Answers1

0

The ret instruction doesn't return to the main but it returns from the main to start the termination of your program. The loop you written isn't a function, you are just jumping back to an earlier line of your code and you don't need to terminate that with a ret instruction. Though you need that ret to terminate your program.

To answer the question about where your values go, they don't go anywhere. If we simplify things a little bit and don't consider context switches, your values remain physically stored in the registers until you or some piece of other code in case of a function call reuses them. To find out what to do with registers at function calls and how to pass arguments to functions look into calling conventions.

Corrosive
  • 71
  • 5
  • Thank You!, and I have another question, what are the common addressing modes supported by 64-bit CPU? – Dan Nov 21 '17 at 15:59
  • 1
    You are welcome! About the addressing modes there are much better texts to read than what I could possibly write in a comment, so I would recommend the text I learned them from instead. Jonathan Bartlett's Programming from the Ground Up is a very nice introductory book and it's free, it covers 32 bit Linux programming, but in the case of addressing modes it doesn't really matter. Reading the section called Addressing Modes should clarify the concept. – Corrosive Nov 21 '17 at 18:05
  • @Dan: See https://stackoverflow.com/questions/34058101/referencing-the-contents-of-a-memory-location-x86-addressing-modes (the answer uses NASM syntax, but AT&T syntax can express all the same addressing modes.) The new addressing mode in x86-64 is RIP-relative, and is very useful for position-independent code. And BTW, see https://stackoverflow.com/tags/x86/info for more links to guides/docs (including the PGU book). – Peter Cordes Nov 21 '17 at 23:32