NASM Forum > Example Code
My own 64-bit `puts' instruction (No length required)
MediocreVeg1:
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
.cntloop:
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
ret
--- 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
syscall
ret
--- 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.
MediocreVeg1:
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!
Best,
Frank
MediocreVeg1:
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.
MediocreVeg1:
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
%endmacro
--- 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.
Navigation
[0] Message Index
[#] Next page
Go to full version