Reputation: 4767
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
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