Finally i got it! My first program with the famous win32 (the apis) :bgrin:
Of course the code it's so simple that i shame my self for posting, but i will if you want. :lol:
One question for you who know: The masm32rt.inc includes the directives for the memory model? (.model flat)
Thanks...
:redface:... :lol:
felipe,
Post the example, we have all been there and perhaps we can help a bit.
Quote from: felipe on April 26, 2017, 12:13:44 PMThe masm32rt.inc includes the directives for the memory model? (.model flat)
Go have a look! It's a plain text file, all editors can open it (don't save it, though).
Quote from: jj2007 on April 26, 2017, 04:27:07 PM
Quote from: felipe on April 26, 2017, 12:13:44 PMThe masm32rt.inc includes the directives for the memory model? (.model flat)
Go have a look! It's a plain text file, all editors can open it (don't save it, though).
You are right. I did it some day, but i will do it again. Well here is the simplest program:
.386
.model flat,stdcall
option casemap:none
include c:\masm32\include\masm32rt.inc
.stack 4096
.data
head byte 'The first',0
inside byte 'Hello!',0
.code
start:
main proc
call push_parameters
call ExitProcess ; Windows function.
main endp
push_parameters proc
push 0 ; Style of message box.
mov ebx,offset head
push ebx
mov ebx,offset inside
push ebx
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
end start
I will later be online now i'm hurry, thanks for your interest. :t
felipe,
; .386
; .model flat,stdcall
; option casemap:none
include c:\masm32\include\masm32rt.inc ; If you use this, you don't use the one before it.
.stack 4096 ; this is not used in 32 bit Windows. In 32 bit you set the stack if necessary in the linker options.
deleted
Here is a nice tidy MASM32 simple text output, does the same as a hello world but in Spanish.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.data
text db "Hola hombre",0 ; display text
ptext dd text ; pointer to display text
crlf db 13,10,0 ; carriage return, line feed pair
pcrlf dd crlf
.code
start: ; start execution here
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
; -------------------------------------------
; StdOut is a procedure in the MASM32 library
; -------------------------------------------
invoke StdOut,ptext ; display message text
invoke StdOut,pcrlf ; add a crlf pair
invoke StdOut,pcrlf ; add a crlf pair
inkey ; macro to wait for a key press to exit
; -------------------------------------
; ExitProcess is a Windows API function
; -------------------------------------
invoke ExitProcess,0 ; exit the current process
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start ; tell MASM where the code end is
Congrats Felipe!
Ok, thanks a lot. I have two questions: 1) Is offset a directive from masm or a instruction mnemonic from intel?
and 2) Why i can't have the offset in a register with the lea instruction? I mean, there wasen't errors in the assembly process, but the program didn't run in windows (windows gave me an error using the lea for load a register with the desired offset).
:redface:
.data
text db "Hola hombre",0 ; display text
.code
start: ; start execution here
mov eax, offset text
lea edx, text ; NOT: offset text (sorry for confusing you, Felipe!!)
...
Both instructions do the same, but lea is one byte longer. "offset" is not an opcode, but it is an instruction used by MASM and its clones (and maybe others, I don't know).
When addressing local variables, e.g. with
invoke MessageBox, 0, addr localtext, addr localtitle, MB_OK
lea is being used together with ebp.
To understand these things better,
- get Olly (http://www.ollydbg.de/odbg201.zip)
- unzip it to \Masm32\OllyDbg
- open your program in RichMasm
- insert an int 3 after start:
- hit F6 to build and launch Olly
- hit F9 to arrive at the int 3
- hit F7 to continue step by step (same for F8, except that it will not go inside procs)
deleted
But i coded:( lea ebx,memory_location) first, and the assembly was correct. But windows couldn't run the program, why? :redface:
Quote from: felipe on April 27, 2017, 04:14:39 AMBut windows couldn't run the program, why? :redface:
Can't find my crystal ball right now, can you post the complete code please?
It was the same code of above man, but instead of the lines: (mov ebx,offset head) and (mov ebx,offset inside) was:
(lea ebx,head) and (lea ebx,inside).
It's the problem because i treated the instruction (lea) like in real mode? So like this instruction is used for dinamically addresing and the OS is in protected mode (moving the actual locations of the code) that dosen't work. So the correct instruction would be: (lea ebx, offset memory_location)? :redface:
both below will work. You may have missed something else
push_parameters proc
push 0 ; Style of message box.
;mov ebx,offset head ;<== this
lea ebx, head ;<== or this
push ebx
;mov ebx,offset inside
lea ebx, inside
push ebx
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
deleted
Quote from: LordAdef on April 27, 2017, 04:54:08 AM
both below will work. You may have missed something else
push_parameters proc
push 0 ; Style of message box.
;mov ebx,offset head ;<== this
lea ebx, head ;<== or this
push ebx
;mov ebx,offset inside
lea ebx, inside
push ebx
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
No man. The assembly here in windows 8.1 with the masm32 sdk works fine, but windows can't run the program. :redface:
Quote from: nidud on April 27, 2017, 04:57:34 AM
LEA should work, but it may be simpler to just push the offset in this case.
include c:\masm32\include\masm32rt.inc
.data
head byte 'The first',0
inside byte 'Hello!',0
.code
main proc
call push_parameters
call ExitProcess ; Windows function.
main endp
push_parameters proc
push 0 ; Style of message box.
push offset head
push offset inside
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
end main
Yes i know that, you can push memory into the stack directly (the offset) in one of the unique cases of memory to memory operations. But i wasn't sure if the offeset was a directive or an instruction (intel). But i wanted to do more (and i like this way more) code with the intel mnemonics and not use to much the directives (just where it's necesary of course). I did it almost for playing and testing.
QuoteSo the correct instruction would be: (lea ebx, offset memory_location)? :redface:
Ok, but you confuses us when you write the line above. If you buit it without errors, and it´s not running, the problem is somewhere else.
QuoteIt's the problem because i treated the instruction (lea) like in real mode?
Forget real mode, your asm scope is within the boundaries of protected mode. The problem is somewhere else.
Well, let´s wait for the gurus to come and help, and I hope I could´ve helped somehow
Quote from: LordAdef on April 27, 2017, 05:14:13 AM
QuoteIt's the problem because i treated the instruction (lea) like in real mode?
Forget real mode, your asm scope is within the boundaries of protected mode. The problem is somewhere else.
Well, let´s wait for the gurus to come and help, and I hope I could´ve helped somehow
Man thanks for your help, but i think that this have something to do with the problem... :eusa_snooty:
Sure, I´m curious too!
But maybe it's an stupid idea because if the data moves (in hands of the O.S.) then the instruction that has access to this dynamic data (lea) should work. In the other part this variables are statics, right? (at least in the way that in the source code they appear declared) So what is it?... ::)... :lol:
Quote from: felipe on April 27, 2017, 04:43:51 AM
It was the same code of above man, but instead of the lines: (mov ebx,offset head) and (mov ebx,offset inside) was:
(lea ebx,head) and (lea ebx,inside).
Here is the testbed. Your code works fine with IF 0 and IF 1, and there is no reason why it shouldn't.
.386
.model flat,stdcall
option casemap:none
include \masm32\include\masm32rt.inc
.stack 4096
.data
head byte 'The first',0
inside byte 'Hello!',0
.code
start:
main proc
call push_parameters
call ExitProcess ; Windows function.
main endp
push_parameters proc
push 0 ; Style of message box.
if 1
lea ebx, head
push ebx
lea ebx, inside
push ebx
else
mov ebx,offset head
push ebx
mov ebx,offset inside
push ebx
endif
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
end start
You are right! It's really rare. I have tested using the lea again and it worked. Maybe it was a momentary problem in the O.S.? Like i sayed there wasn't errors in the assembly time nor in the linking. Well, i should study more, i don't want to confuse anybody nor myself :lol:
Thanks all for your help, i appreciate. :t
http://masm32.com/board/index.php?topic=1425.msg14577#msg14577 (http://masm32.com/board/index.php?topic=1425.msg14577#msg14577)
These is usefull for newbies who has similar confusions... ;)... :lol:
hello sir felipe;
imagine that you have a table in front of you, you can deal with fields contents of that table or you can point to fields of that table.
This is how we can deal with memory by processor point of view, or we can point to an memory address or we can get contents of memory address.
Quote from: mineiro on April 27, 2017, 06:30:35 AM
hello sir felipe;
imagine that you have a table in front of you, you can deal with fields contents of that table or you can point to fields of that table.
This is how we can deal with memory by processor point of view, or we can point to an memory address or we can get contents of memory address.
I know, i know... :lol:
Quote from: LordAdef on April 27, 2017, 05:14:13 AM
QuoteSo the correct instruction would be: (lea ebx, offset memory_location)? :redface:
Ok, but you confuses us when you write the line above. If you buit it without errors, and it´s not running, the problem is somewhere else.
I just want to say that i took that from:
Quote from: jj2007 on April 27, 2017, 03:21:14 AM
.data
text db "Hola hombre",0 ; display text
.code
start: ; start execution here
mov eax, offset text
lea edx, offset text
...
Both instructions do the same,
:lol:
The correct syntax is indeed
lea edx, text
and not
lea edx, offset text
I have corrected my post accordingly. However, both instructions produce exactly the same code, and therefore we still have to find the true reason for "windows can't run the program". You cannot reproduce the problem, I suppose?
Quote from: jj2007 on April 27, 2017, 08:50:39 AM
The correct syntax is indeed
lea edx, text
and not
lea edx, offset text
I have corrected my post accordingly. However, both instructions produce exactly the same code, and therefore we still have to find the true reason for "windows can't run the program". You cannot reproduce the problem, I suppose?
Jochen, as far as i know
lea edx,text is the same as
mov edx, offset text.
lea is used when we have
local variables.
See you :t
Quote from: jj2007 on April 27, 2017, 08:50:39 AM
You cannot reproduce the problem, I suppose?
No man, but i just have done another little program that creates a new file (with the CreateFile api function) and i did have the same problem: Assembly and linking correct, but windows coudn't run the program. Then i checked the code and i was omiting a ret instruction. I did correct that and it work.
In ms-dos this kind of problems would be funny, but here windows protects the system, wich it's funny too. ;)... :lol:
a basic abstration means that mov and lea and others processors instructions are instructions, not abstractions.
Quote from: LordAdef on April 27, 2017, 04:54:08 AM
both below will work. You may have missed something else
push_parameters proc
push 0 ; Style of message box.
;mov ebx,offset head ;<== this
lea ebx, head ;<== or this
push ebx
lea means move address of varible to register;
;mov ebx,offset inside
lea ebx, inside
push ebx
push 0 ; No window, no handle?
call MessageBoxA ; Windows function.
ret
push_parameters endp
QuoteI did correct that and it work.
good to know!
Here are the normal variations.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
; *********************************
; *********************************
; build with "Assembler & Link"
; *********************************
; *********************************
.data
titl db "Example",0
doff db "Using the data OFFSET",0
lead db "Loading the effective address",0
tdat db "Using POINTERS to the data",0
; -------------------------------------
; DWORD pointers to the above text data
; -------------------------------------
pttl dd titl
poff dd doff
padr dd lead
pdat dd tdat
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
; ----------------------------
; using the OFFSET of the data
; ----------------------------
push MB_OK
push OFFSET titl
push OFFSET doff
push 0
call MessageBox
; -------------------------------------------
; load effective address with instruction LEA
; -------------------------------------------
push MB_OK
lea eax, titl
push eax
lea eax, lead
push eax
push 0
call MessageBox
; --------------------------
; using POINTERS to the data
; --------------------------
push MB_OK
push pttl
push pdat
push 0
call MessageBox
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Any reason why you are not "invoking" this MessageBox?
Just to show felipe how its done manually.
oh, I see! Cheers
Thanks a lot Hutch. So that 'p' is required for the 'pointers type'? And they should be always 32 bit long? (At least in 32 bit programming).
Quote from: felipe on April 28, 2017, 05:27:32 AM
So that 'p' is required for the 'pointers type'?
You can use whatever you want, but search for
hungarian notation. And yes, 32 bits wide.
Hi felipe,
The names you use as variable are your own choice, what I have tried to do is use a consistent naming system so that you can understand what you write. A pointer is the address of data placed in a DWORD variable and in 32 bit Windows, it is always a 32 bit unsigned variable. In 64 bit it is always a 64 bit variable.
You can think of a pointer like this.
.DATA
MyVariable dd 0
................
.CODE
................
lea eax, someitem ; get the address of whatever you need
mov MyVariable, eax ; write it to a variable so it is a POINTER to the data
Clear as water, thanks a lot! I was confused first, but now i realized that you assigned to the dwords variables the addresses of the other variables. :t
Here is another detailed example, copy & paste & build & run:include \masm32\include\masm32rt.inc
.data
MyByteArray BYTE "Byte array means an ANSI string", 0
MyPointer DWORD MyByteArray ; this dword variable points to the string
.data?
buffer db 100 dup(?) ; uninitialised, i.e. contains zeros
.code
start:
mov eax, MyPointer ; two instructions that do the same: in both cases,
mov esi, offset MyByteArray ; the register is now a pointer to the string
.if eax==esi
print "eax==esi", 13, 10 ; this is what we suspected ;-)
.else
print "eax<>esi", 13, 10 ; this would be rather surprising
.endif
mov edi, offset buffer ; edi contains a pointer to the buffer
push edi ; keep a copy
print esi, 13, 10 ; display the byte array
mov ecx, sizeof MyByteArray-1 ; we use ecx as a counter
.Repeat
lodsb ; load al from esi, increment esi by one
or al, 32 ; for you to find out ;-)
stosb ; store al to [edi], inc edi
dec ecx
.Until Sign? ; stop when dec ecx sets the sign flag, i.e. ecx=-1
pop edi ; get the copy back
inkey edi ; and use it
exit
end start
You may notice that the cursor blinks one byte after the string. Use Olly (http://www.ollydbg.de/version2.html) to find out why, and if you need homework, try to eliminate this little bug.
Quote from: jj2007 on April 28, 2017, 12:25:15 PM
Here is another detailed example, copy & paste & build & run:include \masm32\include\masm32rt.inc
.data
MyByteArray BYTE "Byte array means an ANSI string", 0
MyPointer DWORD MyByteArray ; this dword variable points to the string
.data?
buffer db 100 dup(?) ; uninitialised, i.e. contains zeros
.code
start:
mov eax, MyPointer ; two instructions that do the same: in both cases,
mov esi, offset MyByteArray ; the register is now a pointer to the string
.if eax==esi
print "eax==esi", 13, 10 ; this is what we suspected ;-)
.else
print "eax<>esi", 13, 10 ; this would be rather surprising
.endif
mov edi, offset buffer ; edi contains a pointer to the buffer
push edi ; keep a copy
print esi, 13, 10 ; display the byte array
mov ecx, sizeof MyByteArray-1 ; we use ecx as a counter
.Repeat
lodsb ; load al from esi, increment esi by one
or al, 32 ; for you to find out ;-)
stosb ; store al to [edi], inc edi
dec ecx
.Until Sign? ; stop when dec ecx sets the sign flag, i.e. ecx=-1
pop edi ; get the copy back
inkey edi ; and use it
exit
end start
You may notice that the cursor blinks one byte after the string. Use Olly (http://www.ollydbg.de/version2.html) to find out why, and if you need homework, try to eliminate this little bug.
Thanks. :t
I haven't learned the use of olly yet, but i will do that soon as i can. I tryed to run the program, both in directly with the mouse and the console, but nothing happen (well, the program stay in running so i have to terminate the process with the task manager).
Now, i know why you did the or operation: It's for convert each letter in the string in an lowercase letter.