The MASM Forum

General => The Campus => Topic started by: felipe on April 26, 2017, 12:13:44 PM

Title: My first program!
Post by: felipe on April 26, 2017, 12:13:44 PM
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:
Title: Re: My first program!
Post by: hutch-- on April 26, 2017, 02:37:08 PM
felipe,

Post the example, we have all been there and perhaps we can help a bit.
Title: Re: My first program!
Post by: 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).
Title: Re: My first program!
Post by: felipe on April 26, 2017, 11:10:50 PM
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
Title: Re: My first program!
Post by: hutch-- on April 26, 2017, 11:20:32 PM
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.
Title: Re: My first program!
Post by: nidud on April 26, 2017, 11:37:39 PM
deleted
Title: Re: My first program!
Post by: hutch-- on April 27, 2017, 02:15:43 AM
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
Title: Re: My first program!
Post by: LordAdef on April 27, 2017, 02:19:47 AM
Congrats Felipe!
Title: Re: My first program!
Post by: felipe on April 27, 2017, 02:59:27 AM
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:
Title: Re: My first program!
Post by: 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, 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)
Title: Re: My first program!
Post by: nidud on April 27, 2017, 03:53:35 AM
deleted
Title: Re: My first program!
Post by: felipe on April 27, 2017, 04:14:39 AM
But i coded:( lea ebx,memory_location) first, and the assembly was correct. But windows couldn't run the program, why?  :redface:
Title: Re: My first program!
Post by: jj2007 on April 27, 2017, 04:27:48 AM
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?
Title: Re: My first program!
Post by: 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).

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:
Title: Re: My first program!
Post by: 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
Title: Re: My first program!
Post by: nidud on April 27, 2017, 04:57:34 AM
deleted
Title: Re: My first program!
Post by: felipe on April 27, 2017, 05:00:27 AM
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:
Title: Re: My first program!
Post by: felipe on April 27, 2017, 05:09:36 AM
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.
Title: Re: My first program!
Post by: 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.

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
Title: Re: My first program!
Post by: felipe on April 27, 2017, 05:22:46 AM
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:
Title: Re: My first program!
Post by: LordAdef on April 27, 2017, 05:28:22 AM
Sure, I´m curious too!
Title: Re: My first program!
Post by: felipe on April 27, 2017, 05:38:43 AM
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:
Title: Re: My first program!
Post by: jj2007 on April 27, 2017, 05:52:04 AM
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
       
Title: Re: My first program!
Post by: felipe on April 27, 2017, 06:18:46 AM
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
Title: Re: My first program!
Post by: felipe on April 27, 2017, 06:22:30 AM
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:
Title: Re: My first program!
Post by: 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.
Title: Re: My first program!
Post by: felipe on April 27, 2017, 06:33:55 AM
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:
Title: Re: My first program!
Post by: felipe on April 27, 2017, 06:38:09 AM
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:
Title: Re: My first program!
Post by: 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?
Title: Re: My first program!
Post by: RuiLoureiro on April 27, 2017, 09:12:17 AM
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
Title: Re: My first program!
Post by: felipe on April 27, 2017, 10:52:07 AM
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:
Title: Re: My first program!
Post by: mineiro on April 27, 2017, 10:56:15 AM
a basic abstration means that mov and lea and others processors instructions are instructions, not abstractions.
Title: Re: My first program!
Post by: newrobert on April 27, 2017, 11:11:59 AM
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
Title: Re: My first program!
Post by: LordAdef on April 27, 2017, 11:44:49 AM
QuoteI did correct that and it work.

good to know!
Title: Re: My first program!
Post by: hutch-- on April 27, 2017, 02:19:41 PM
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
Title: Re: My first program!
Post by: LordAdef on April 27, 2017, 07:52:58 PM
Any reason why you are not "invoking" this MessageBox?
Title: Re: My first program!
Post by: hutch-- on April 27, 2017, 07:54:29 PM
Just to show felipe how its done manually.
Title: Re: My first program!
Post by: LordAdef on April 27, 2017, 08:03:32 PM
oh, I see! Cheers
Title: Re: My first program!
Post by: felipe on April 28, 2017, 05:27:32 AM
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).
Title: Re: My first program!
Post by: jj2007 on April 28, 2017, 06:21:54 AM
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.
Title: Re: My first program!
Post by: hutch-- on April 28, 2017, 10:43:53 AM
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

Title: Re: My first program!
Post by: felipe on April 28, 2017, 10:59:46 AM
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
Title: Re: My first program!
Post by: 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.
Title: Re: My first program!
Post by: felipe on April 29, 2017, 12:06:34 AM
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.