You have one major problem here, and two other major problems that might not be visible with this particular caller:
- You forgot to set
edx to the string length. The system call you're using is
sys_write(int fd, const char *buf, size_t len);, so the len you're passing is whatever garbage your caller left in edx.
If that doesn't make sys_write return -EFAULT without printing anything, then maybe you're printing a bunch of binary garbage before it detects a problem, if you ended up with a very large len? Hmm, write probably checks the whole range before writing anything, so maybe you ended up with a medium-sized value in edx and just printed some binary garbage after your strings. Your strings should be there at the start of your output, though.
Use strace ./my_program to find out, or GDB to look at edx before the call. (strace won't actually work right for int 0x80 from 64-bit code; it decodes as if you were using the native 64-bit syscall ABI).
You clobber the caller's rbx without saving/restoring it, violating the calling convention (the x86-64 System V ABI) where rbx is a call-preserved register. See http://agner.org/optimize/ for a nice doc about calling conventions. This may have no effect; your main probably doesn't compile to code that uses rbx for anything, so the rbx you're destroying is "owned" by the CRT start function that calls main.
Strangely, you save/restore rbp even though you don't use it at all.
Most importantly, you're using the 32-bit int 0x80 ABI from 64-bit code!! This is why I've been saying that write takes its length are in edx, not rdx, because the 32-bit int 0x80 ABI is exactly the same ABI that 32-bit user-space can use, where it only looks at the low 32 bits of registers.
Your code will break with pointers outside the low 32 bits of virtual address space. e.g. if you compiled with gcc -fPIE -pie, even those string literals in the .rodata section will be outside the low 32 bits, and sys_write will probably return -EFAULT without doing anything.
-pie is the default for gcc on many modern Linux distros, so you're "lucky"(?) that your program printed anything at all instead of just having write fail with -EFAULT. You aren't checking error return values, and it doesn't segfault your program the way it would if you tried to read/write from a bad point in user-space, so it fails silently.
As @fuz points out, Why cant i sys_write from a register? shows some example code for using the 64-bit syscall for sys_write, but it hard-codes a length. You're going to need to strlen your string, either with the libc function or with a loop. (Or a slow but compact repe scasb).
sys_write1 for x86_64? Also, you should setrdxto the number of bytes to write.int 0x80ABI from 64-bit code, so the call numbers are fromunistd_32.h. The arg-passing registers are ebx,ecx,edx, etc. (not rdi,rsi,rdx, etc.), so you can only use 32-bit pointers and lengths. But anyway, yes, you neededx=strlen()