title: Write function 'print_string' which accepts a pointer to a null-terminated string and prints it to stdout
body: <p>I am currently going through Zhirkov's book, "Low Level Programming" for the purpose of self-learning.</p>
  
  <p>I am stuck on the end of chapter two, the assignment. I have written the first function, <code>string_length</code>, which accepts a pointer to a string and returns its length. I have also created a test <code>print_str</code> function which prints out a pre-defined string of bytes.</p>
  
  <p>I cannot figure out how to write <code>print_string</code> as defined by the author:
  <code>print_string: accepts a pointer to a null-termianted string and prints it to stdout</code></p>
  
  <pre><code>section .data
  string: db "abcdef", 0
  
  string_str:
      xor rax, rax
      mov rax, 1        ; 'write' syscall
      mov rdi, 1        ; stdout
      mov rsi, string   ; address of string
      mov rdx, 7        ; string length in bytes
      syscall
    ret
  
  string_length:
      xor rax, rax
      .loop
          cmp byte [rdi+rax], 0    ; check if current symbol is null-terminated
          je  .end                 ; jump if null-terminated
          inc rax                  ; else go to next symbol and increment
          jmp .loop
      .end
          ret                      ; rax holds return value
  
  section .text
  
  _start:
      mov rdi, string   ; copy address of string
      call print_str
  
      mov rax, 60
      xor rdi, rdi
      syscall
  </code></pre>
  
  <p>So far, I have:</p>
  
  <pre><code>print_string:
      push rdi           ; rdi is the argument for string_length
      call string_length ; call string_length with rdi as arg
      mov rdi, rax       ; rax holds return value from string_legnth
      mov rax, 1         ; 'write' syscall
  </code></pre>
  
  <p>This is my updated print_string function, which, works. Sort of. It prints the string to stdout, but then I am met with: <code>illegal hardware instruction</code></p>
  
  <pre><code>print_string:
      push rdi               ; rdi is the first argument for string_length
      call string_length
      mov rdx, rax           ; 'write' wants the byte length in rdx, which is
                             ; returned by string_length in rax
      mov rax, 1             ; 'write'
      mov rdi, 1             ; 'stdout'
      mov rsi, string        ; address of original string. I SUSPECT ERROR HERE
      syscall
    ret
  </code></pre>