NASM Forum > Example Code
My own 64-bit `puts' instruction (No length required)
fredericopissarra:
--- Quote from: MediocreVeg1 on January 18, 2021, 03:06:55 PM ---Maybe I'm not understanding how scas works, but isn't the result of scasb stored in rbx in 64-bit assembly? That's why I cleared it with XOR before using scasb and why I substracted it from rdi (which has starting address of string). I'm probably wrong here though.
--- End quote ---
SCASB reads from ES:RDI and compares with AL, affecting the flags, and updates RDI. With REP (or REPNZ) prefix it does RCX times while ZF=0 (hence the NZ). So strlen could be implemented as:
--- Code: ---; Same as: size_t strlen( const char * );
; the function assumes ALL strings will be NUL terminated.
strlen_:
xor eax,eax
lea ecx,[rax-1] ; Limiting the string size to 2³²-1, max.
mov rdx,rdi
repnz scasb ; Scan for '\0'...
sub rdi,rdx
mov rax,rdi ; returns size in RAX.
ret
--- End code ---
--- Quote from: MediocreVeg1 on January 18, 2021, 03:06:55 PM ---Wouldn't the assembler get confused if I used 64-bit syscalls on 32-bit registers? Or if I put some arguments of a syscall in R?? registers and others in E?? registers?
--- End quote ---
E?? registers are the lower part of R?? registers. And, in x86-64 mode, when you change E?? register the upper 32 bits of R?? register is automatically zeroed... Instructions using R?? registers need to insert an prefix (REX prefix), with E?? no prefix...
--- Quote from: MediocreVeg1 on January 18, 2021, 03:06:55 PM ---Wouldn't the assembler
--- Quote ---Notice in my routine, if '\0' isn't found in a block of 2³²-1 bytes it returns -1 (all bits set) in RAX. This allows you to test an error:
--- End quote ---
... Wouldn't this event be highly unlikely though? ...
--- End quote ---
You are right!... It easier to assume the routine expects ALL strings to be zero terminated...
munair:
--- Quote from: fredericopissarra on July 22, 2023, 11:46:12 AM ---So strlen could be implemented as:
--- Code: ---; Same as: size_t strlen( const char * );
; the function assumes ALL strings will be NUL terminated.
strlen_:
xor eax,eax
lea ecx,[rax-1] ; Limiting the string size to 2³²-1, max.
mov rdx,rdi
repnz scasb ; Scan for '\0'...
sub rdi,rdx
mov rax,rdi ; returns size in RAX.
ret
--- End code ---
--- End quote ---
That would return string length + 1. So alternatively:
--- Code: --- xor eax, eax
lea ecx, [rax - 1]
mov rdx, rdi
repnz scasb
sub rdi, rdx
;mov rax, rdi
lea rax, [rdi - 1] ; not counting the null terminator
--- End code ---
fredericopissarra:
--- Quote from: munair on July 22, 2023, 03:38:17 PM ---That would return string length + 1....
--- End quote ---
Ops... sorry... my bad...
alCoPaUL:
you can just iterate displaying letters until it's \0..
so you can display a 1 gigabyte or more worth of strings and then cut it when it's \0.
fredericopissarra:
--- Quote from: MediocreVeg1 on January 18, 2021, 03:06:55 PM ---Maybe I'm not understanding how scas works, but isn't the result of scasb stored in rbx in 64-bit assembly?
--- End quote ---
Nope! scasb tests AL against ES:[RDI], setting the flags. repnz scasb does the same, RCX times while ZF=0.
--- Quote from: MediocreVeg1 ---Wouldn't the assembler get confused if I used 64-bit syscalls on 32-bit registers? Or if I put some arguments of a syscall in R?? registers and others in E?? registers?
--- End quote ---
Nope! E?? registers are the lower 32 bits of R?? registers. When you use a R?? register the instrunction is prefixed with a REX prefix (and, an immediate can be bigger), like, for example:
--- Code: --- mov eax,-1 ; B8 FF FF FF FF
mov rax,-1 ; 48 B8 FF FF FF FF FF FF FF FF
--- End code ---
When using EAX the upper 32 bits are automagically (hehe) zeroed.
--- Quote from: MediocreVeg1 ---Yeah, I put it into my procedure as well after you showed your example. Wouldn't this event be highly unlikely though? I think 2^32-1 is like 4294967295 bytes so every single byte after the starting address of the string would have to be non-zero, right?
--- End quote ---
That's why it doesn't make sense using R?? registers to hold string lengths...
[]s
Fred
Navigation
[0] Message Index
[*] Previous page
Go to full version