-6

Can you explain this code?

.data
.globl greet
greet:
.string "Hello world."

.text
.global main
main:
    pushq   %rbp
    movq    %rsp,       %rbp
    movq    $greet,     %rdi
    call    puts
    movq    $0,         %rax
    leave
    ret

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
TheCoder
  • 21
  • 2
  • See https://stackoverflow.com/tags/att/info for the syntax basics, and https://sourceware.org/binutils/docs/as/ for the GAS directives. Looks like clumsy hand-written code for x86-64 Linux for a traditional non-PIE executable; it won't link as a PIE because it [uses a 32-bit absolute address for `greet`](https://stackoverflow.com/questions/57212012/how-to-load-address-of-function-or-label-into-register). (And I say "clumsy" because `main` returns `int`, not `long`, so there's no point in using `movq`) – Peter Cordes May 02 '21 at 03:52
  • This wouldn't work on MacOS because of the 32-bit absolute address, and wouldn't work on Windows because Windows uses a different calling convention. It might work on some BSD versions, IDK, but it's probably easiest to call it a Linux example. (And then only for non-PIE executables; building this with `gcc foo.S` on a modern distro where PIE is the default would also choke on `puts` instead of `call puts@plt` or gcc -fno-plt style `call *puts@GOTPCREL(%rip)`, as well as the 32-bit absolute address) – Peter Cordes May 02 '21 at 04:04

2 Answers2

1
  • .data this the place were you put headers and defines to use in main:
  • .global greet .global means the label will be the visible to the linker because in main we will use it.
  • greet: the label initializing
  • pushq %rbp: push rbp register onto the stack
  • movq %rsp, %rbp: RBP = RSP
  • movq $greet, %rdi: RDI = address of greet label
  • call puts: api to print string, which looks for a pointer in RDI
  • movq $0, %rax: nop rax(clear data)
  • leave: exit label
  • ret: termination
Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
coderx64
  • 109
  • 8
  • 2
    There is no `greet` function here, that label is on data. The function-call is to `puts`, passing the address of the global `char greet[] = "...";` – Peter Cordes May 02 '21 at 03:45
  • `greet:` will be visible within the same file even without `.globl`. Just `greet:` alone is like `static char greet[]` in C. Using `.globl` makes it like a C global var (still in static storage-class, but without the file-scope visibility limit). – Peter Cordes May 02 '21 at 03:58
  • Also, terminology nitpick: generally avoid the word "storing" when not writing memory. *load* the address of `greet` into RDI. (And it's not loading the data, that's the point of the `$`.) – Peter Cordes May 02 '21 at 04:00
  • 1
    In `movq %rsp, %rbp`, RBP is the *destination*. I fixed that for you. Also, `leave` doesn't "exit" from a label, it's an instruction (https://www.felixcloutier.com/x86/leave). Exactly equivalent to `mov %rbp, %rsp` ; `pop %rbp`. Also, `ret` isn't "termination", it pops a return address into RIP, returning control to the CRT startup code that called main. – Peter Cordes May 02 '21 at 04:25
  • 1
    Also `mov $0, %rax` isn't a NOP, it sets RAX = 0. Main's caller will look for the `int main` return address in EAX, and pass that to the libc `exit()` function. This answer also misses explaining *why* the code messes around with RBP at all (traditional frame pointer, which works as a way tore-align the stack by 16 before a function call.) – Peter Cordes May 02 '21 at 04:27
0

I do not program in Assembly but I'll try:

  • .data: Declare new RAM address. .data means .section .data, which switches to the .data section. (Thanks Peter Cordes for pointing this out!)
  • .globl greet: Sets the variable greet to global visibility.
  • greet: declares greet.
  • .string "Hello World" sets it to Hello World.
  • the rest of the code prints it out.
  • `.data` doesn't really "declare a new RAM address". It sets the assembler's current section to `.data`, i.e. a shortcut for `.section .data`. Just like `.text` switches (back) to the `.text` section, so later lines will assemble bytes into that section. (It's up to the linker to map sections to absolute addresses, when linking this into a non-PIE executable.) https://sourceware.org/binutils/docs/as/Data.html – Peter Cordes May 02 '21 at 03:49
  • Also, `.globl greet` doesn't *declare* anything; it sets the visibility attribute for `greet` *if* this source file happens to define that symbol on another line before or after. (Which it does with a `greet:` label). If there had been no `greet:`, then `.globl greet` would have absolutely no effect. – Peter Cordes May 02 '21 at 03:54