NASM Forum > Example Code

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

(1/4) > >>

So I've been having a bit of difficulty regarding procedures, and the people on this forum helped a lot (and helped me understand 64-bit assembly in general). So in return, I want to help others who may be having difficulty like me too with the `puts' procedure i made. But the main advantage of the procedure - not having to enter the length - requires another procedure `strlen', which calculates the length of the string (not including the terminating 0 character). It takes rdi (which should hold the string) as a parameter and returns the length in rax. So here it is:

--- Code: ---strlen:
    xor rax, rax ; Return value, will count string length
    dec rdi
    inc rax
    inc rdi
    cmp byte [rdi], 0 ; Terminating character
    jnz strlen.cntloop

    dec rax ; So that it does not include the last terminating character
--- End code ---
Thanks to this, the actual printing procedure is really simple. It also takes rdi as a parameter and prints the string in the register:

--- Code: ---puts:
    mov rsi, rdi
    call strlen
    mov rdx, rax
    mov rax, 1
    mov rdi, rax
--- End code ---

Note that the string doesn't need to have a 0 character at the end for this to work, but it would be better if you did put it.

This isn't as advanced as the `puts' macro I made, which didn't require the argument to be a variable and could take an infinite amount of arguments, but it couldn't print variables of .bss and too macros is probably a bad idea. Anyway, do give me any suggestions to improve the code if you feel it could be better.

UPDATE: I realised an issue with the procedure related to the way section .data works. From what I can tell, if you do this:

--- Code: ---achar db "H"
bchar db "F"
--- End code ---
the variables will be stored in the memory side-by-side with no space in-between, so no terminating character in-between. This means that if you print achar, it'll print bchar right after that. Due to this, I HIGHLY RECOMMEND YOU PUT THE NULL CHARACTER YOURSELF AT THE END OF EACH STRING. Apart from that, the rest is fine.

Frank Kotler:
Looks as if you've reinvented "gets". No protection against overflow.  Take it away!


What do you mean by that? I actually haven't tried to make a `gets' without specifying the size because I'm not sure if that is possible with how I'm getting length currently.

Oh right, if you are talking about the going to the other vairable thing, yeah, it is a bit annoying. If you really can't put the 0 at the end, you can override db to automatically put a 0 with this macro:

--- Code: ---%macro db 1+
    db %1, 0

--- End code ---
(The plus will make it a greedy parameter so %1 will include all args)
if you don't want to override db or dont want to do this with every dx instruction you can rename it to something else too.


[0] Message Index

[#] Next page

Go to full version