I am newbie, please help:
print a - z
mov ecx,96
.REPEAT
inc ecx
push ecx
;here I want to print the char represented in ecx, 97 = 'a', 98 = 'b'..etc
pop ecx
.UNTIL ecx == 122 ; untill 'z'
the simplest solution would be :
mov ecx,'a'
.REPEAT
push ecx
print esp,10,13
pop ecx
inc ecx
.UNTIL ecx == 'z'
but you wouldn't understand how it works..
.data
buffer db 0,0; we will not use more than 2 chars (1+Null terminator)
.code
mov cl,'a'
.REPEAT
mov buffer,cl; mov to first position in buffer
push ecx; preserve the register
invoke StdOut,addr buffer; call stdout with address of buffer
pop ecx; restore
inc cl
.UNTIL cl == 'z'
or you could do it without registers
.data
buffer db 'a',0; we will not use more than 2 chars (1+Null terminator)
.code
.REPEAT
invoke StdOut,addr buffer; call stdout with address of buffer
inc byte ptr buffer ; works with or without "byte ptr"
.UNTIL byte ptr buffer == 'z'
when I run the code above, i get a error
"test.exe has encountered a problem and needs to close. We are sorry for the inconvenience."
It works for me.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
buffer db 'a',0; we will not use more than 2 chars (1+Null terminator)
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.REPEAT
invoke StdOut,addr buffer; call stdout with address of buffer
inc byte ptr buffer ; works with or without "byte ptr"
.UNTIL byte ptr buffer == 'z'
call wait_key
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
An similar alternative, uses print and inkey. Prints the full a - z.
include \masm32\include\masm32rt.inc
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.data
szBuffer db " ",0 ; space for a character zero terminated string
szCRLF db 13,10,0 ; carriage return line feed zero terminated string
.code
start:
mov szBuffer, "a"
.repeat
print addr szBuffer
inc szBuffer
.until szBuffer > "z" ; needs > or z wont be printed
print addr szCRLF
inkey ; Prints the text Press any key to continue ... then it waits for a key press
exit
end start
[attachment deleted by admin]
this works...thanks.....
hMem DWORD ?
bwrt DWORD ?
.code ; start of main program code
start:
print "start",13,10
sas hMem, "abc"
print hMem,13,10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.REPEAT
invoke ccount,hMem,byte ptr buffer
invoke StdOut,addr buffer;
; here I want to print the result of calling ccount, i.e the number of occurrence of 'a','b',..or 'z' in hMem, can not simply do print eax?
inc byte ptr buffer ; works with or without "byte ptr"
.UNTIL byte ptr buffer == '{'
print "out"
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke ExitProcess, 0 ; return 0;
PUBLIC start
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
ccount proc src:DWORD, char:BYTE
; -----------------------------------------------------
; count any single character in zero terminated string
; -----------------------------------------------------
mov ecx, src
xor eax, eax ; use as counter
mov dl, char
dec ecx
@@:
inc ecx
cmp BYTE PTR [ecx], 0
je @F
cmp [ecx], dl
jne @B
inc eax
jmp @B
@@:
ret
ccount endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start ; end of source code
Why 2nd argument is BYTE?
ccount proc src:DWORD, char:BYTE :lol
because it's for char, maximum of 255 characters
Is it possible to push a byte as a parameter in the stack? :lol
invoke StdOut,addr buffer
invoke ccount,hMem,byte ptr buffer
mov cnt,eax
print str$(cnt)
will do it...
thanks
QuoteIs it posible to push a byte in the stack?
Quoteinvoke ccount, hMem, byte ptr buffer
...
will do it...
Yes, because
byte ptr buffer is DWORD not a BYTE
MASM translate it as:
0040100A A0 A8 61 40 00 mov al, byte ptr ds: [004061A8h]
0040100F 50 push eax ; push byte ptr buffer
00401010 FF 35 48 5E 40 00 push dword ptr ds: [405E48h] ; push hMem
00401016 E8 E7 FF FF FF call 00401002 ; call ccount
Hence,
ccount proc src:DWORD, char:BYTE is a
ccount proc src:DWORD, char:DWORD :lol
Regards,
Lingo
lingjie, it is much easier to use a 256 dword array for what you are doing
.data?
char_count_table dd 256 dup(?)
textbuff db 256 dup(?)
.data
hMem db "aaaaabbbbbbbbccccc"
db "eeeeeffffffdsafascdas"
hMem_size equ ($-hMem)
fmt1 db "Number of occurrences of lettter ""%c"" in string hMem is %u",13,10,0
.code
start:
xor ecx,ecx
mov edx,offset hMem; remove offset if you change it to a variable
.while ecx<hMem_size
movzx eax,byte ptr [edx+ecx]
inc char_count_table[eax*4]
inc ecx
.endw
mov ebx,'a'
.repeat
invoke wsprintf,addr textbuff,addr fmt1,ebx,char_count_table[ebx*4]
invoke StdOut,addr textbuff
inc ebx
.until ebx > 'z'
; if used again
invoke RtlZeroMemory,addr char_count_table,sizeof char_count_table