NASM Forum > Example Code

My own 64-bit `puts' instruction (No length required)

<< < (2/5) > >>

Frank Kotler:
My Mistake. Sorry.

Best,
Frank

MediocreVeg1:
Oh no it's really fine, I agree that the thing can be quite annoying, no denying that. Perhaps I should make another procedure that could allow input for size (basically normal printing but a bit shorter to call). My strlen also seems a bit brute force-ish, looping through the whole string, so I might try to change the code for that too.

fredericopissarra:
if you intend to mimic puts() function from libc, there are 2 things missing:


* it prints an extra '\n' at the end of the string;
* it returns the number of chars printed or -1 in case of error.
A better approach:

--- Code: ---  extern strlen

; int puts_( char * );
;
; puts() returns the number of chars writen or -1 if error.
;
; Entry: RDI points to string
  align 16
puts_:
  push  rbx

  mov   rbx,rdi

  ; glibc strlen() is 100 times faster than that
  ; handmade routine.
  call  strlen wrt ..plt
 
  mov   edx,eax
  mov   rsi,rbx
  mov   ebx,edx     ; save for later.
  mov   eax,1
  mov   edi,eax
  syscall

  test  rax,rax
  js    .error

  ; puts() prints a final '\n'.
  mov   byte [rsp-8],`\n`     ; Use the 'red-zone'.
  mov   eax,1
  mov   edi,eax
  mov   edx,eax
  lea   rsi,[rsp-8]
  syscall
 
  test  eax,eax
  js    .error

  lea   eax,[rbx+1]
  pop   rbx
  ret

.error:
  mov   eax,-1
  pop   rbx
  ret
--- End code ---

MediocreVeg1:
I actually didn't intend to mimic the function, but the extra features do seem helpful. I agree about my strlen being slow too, maybe I'll try a different approach with scasb or something similar. There are definitely some things I need to learn from this example (I tried so much to print a character without making a variable and now I hear about this "red zone"!) and I will try to improve on this. I also will probably want to make another procedure for the newline in case you want to print, for example, a greeting and a variable <name> on the same line. Java has a println() and print() and I've always found this helpful.
Also, do you know what kind of errors could arise from puts?

MediocreVeg1:
[UPDATE] I basically remade my strlen procedure and I think it should be faster now. here's the code:

--- Code: ---strlen:
    mov rcx, 0xff ; (A string may be larger than 255 characters, in which case this would have to increase
    xor rbx, rbx
    repnz scasb ; Will store in rbx
    sub rdi, rbx
    mov rax, rdi
    dec rax ; So as not to include 0
    ret
--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version