samuelbrody1249
samuelbrody1249

Reputation: 4767

Why does this program loop?

I have written the following program, and I was wondering if the behavior of it (1) will always loop; or (2) it has unexpected behavior. I know that I'm missing a ret at the end of the function (and this makes the program run fine), but I was wondering why the program loops when it's not included:

# file.s
.include "utils.s"

.data
str:    .string "Tony"

.text
.globl _start
_start:
    mov $str,   %rdi
    call print_string
    mov $10, %edi
    mov $SYS_EXIT, %eax
    syscall
# utils.o
SYS_EXIT    = 60
SYS_WRITE   = 1
SYS_STDOUT  = 1

print_string:
    # void print_string(char *)
    mov %rdi,       %rsi
    mov $1,         %rdi
    mov $4,         %rdx
    mov $SYS_WRITE, %eax
    syscall

To assemble/link/run:

$ as utils.s -o utils.o && as file.s -o file.o && ld file.o utils.o -o file
$ ./file

When viewing this in gdb after the print_string.syscall it goes back to mov $str, %rdi but why does that occur?

Note: it segfaults when all in one file, but when the print_string is moved to a second file it loops so maybe this is more related to the assembling/linking than the code itself.

Upvotes: 1

Views: 54

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 363980

You did .include "utils.s", so the call print_string will call the copy of print_string you included, not the one in the other .o file (which isn't .globl so isn't even reachable from other files, like a static void foo(char*) function in C).

Execution falls through from the end of print_string to _start.

Don't put code in a file you're going to .include, only definitions of constants and macros. If you did use .globl print_string, then you'd have two conflicting definitions of the same global symbol. And of course you'd be duplicating the definition of every function into every other file that included it, defeating the purpose of linking and functions.


In more detail, your file.s after .include is processed will look like this:

# implicit  .text  - the default section at the top of the file
SYS_EXIT    = 60
SYS_WRITE   = 1
SYS_STDOUT  = 1

print_string:
    # void print_string(char *)
    mov %rdi,       %rsi
    mov $1,         %rdi
    mov $4,         %rdx
    mov $SYS_WRITE, %eax
    syscall

.data
str:    .string "Tony"

.text
.globl _start
_start:
    mov $str,   %rdi
    call print_string
    mov $10, %edi
    mov $SYS_EXIT, %eax
    syscall

Notice that ld won't complain if you omit utils.o because this file has no unresolved symbol references.

Upvotes: 3

Related Questions