Hello.
I'm new to this board, since I just got time to learn this assembly stuff, and I've been reading some help files, but then I stopped at this example, since there's something it's been bothering me. Take a look yourself (ascii "0" is 48, ascii "9" is 57):
NumOnly proc source :DWORD, dest:DWORD
mov ecx, source ; put address into ecx
mov edx, dest ; put address into edx
@@:
mov al, [ecx] ; copy byte at address in ecx to al
inc ecx ; increment address in ecx
; -----------------------------------------------------
; perform byte modification, replacement or omissions
; -----------------------------------------------------
cmp al, 0 ; test for zero first
je @F ; exit loop on ascii zero
cmp al, "0" ; string literal
jb @B ; if below 48 "0", jump back
cmp al, "9" ; string literal
ja @B ; if above 57 "9", jump back
; ------------------------------------------------------
mov [edx], al ; copy byte in al to address in edx
inc edx ; increment address in edx
jmp @B
@@:
mov [edx], al ; copy ascii zero to address in EDI
ret
NumOnly endp
I'm really confused at the last comment sentence, where it mentions EDI, when it's actually working with EDX. By the way, this example is in the asmintro.hlp file in the Help folder, section WORKING WITH STRINGS.
I KNOW this might sound stupid to you, and I have my doubts myself, but I thought it wouldn't hurt to ask: If this an error in the example, and it should have used ESI and EDI since the beginning, instead of ECX and EDX?
Thank you, and I hope I wasn't n00b when asking.
PS: 1. My native tongue isn't english, and 2. I'm a completely newbie to assembly stuff, not only ASM32, but in general. I know this might sound annoying to you, but if you could provide me with examples of pure ASM using MASM, I'd thank you all my life. All the examples I get are done in TASM or NASM.
Hello KaOSoFt
The comment is wrong. When you encounter a discrepancy like this you should trust what you see in the code. The procedure works just as it should. ESI and EDI would have worked OK, but ESI and EDI are among the registers that must be preserved in any code that is called by Windows, directly or indirectly, so by convention they are preserved in all procedures. By using ECX and EDX instead, the procedure can avoid having to preserve any registers (other than those that are preserved automatically). See Register Preservation Convention in the intro.
Here is a console application that performs a quick test of the procedure:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
NumOnly PROTO :DWORD,:DWORD
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
src db "0a1b2c3d4e",0
dst db 10 dup(0)
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
print ADDR src,13,10
invoke NumOnly,ADDR src,ADDR dst
print ADDR dst,13,10
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumOnly proc source :DWORD, dest:DWORD
mov ecx, source ; put address into ecx
mov edx, dest ; put address into edx
@@:
mov al, [ecx] ; copy byte at address in ecx to al
inc ecx ; increment address in ecx
; -----------------------------------------------------
; perform byte modification, replacement or omissions
; -----------------------------------------------------
cmp al, 0 ; test for zero first
je @F ; exit loop on ascii zero
cmp al, "0" ; string literal
jb @B ; if below 48 "0", jump back
cmp al, "9" ; string literal
ja @B ; if above 57 "9", jump back
; ------------------------------------------------------
mov [edx], al ; copy byte in al to address in edx
inc edx ; increment address in edx
jmp @B
@@:
mov [edx], al ; copy ascii zero to address in EDI
ret
NumOnly endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
The MASM32 package includes approximately 200 examples, and about that same number of library procedures, all as source code.
KaOSoFt,
Apologies for the error, its because I generally write a string based procedure and start it with preserving EBX ESI and EDI. When its up and going I usually replace these if it does not use all of the other registers with the registers that don't need to be preserved which lowers the stack overhead. In this case I forgot to fix the comment. :red
That's why I came here: my doubts got solved, and I did sucessfully kept reading the help files.
Thanks you guys for your cooperation. :wink