News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

procedures

Started by theZeroFlag, October 19, 2008, 08:01:47 PM

Previous topic - Next topic

theZeroFlag

assume this begging segment of code

   .486
   .model Flat
   ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
   
   Include io.h             ;include macros input/output - ASCII to binary conversion
   
   
   .stack 100h
   
        .data

   
shortOperand1 WORD ?         ;2 byte operand
shortOperand2 WORD ?         ;2 byte operand
doubleResult DWORD ?         ;4 byte result


.code

ValidateDigitStr   proc   Near32

   push ebp
   mov ebp, esp
   
   push ebx                ;preserve ebx register
   push ecx               ;preserve ecx register
   
   mov ebx, [ebp+8]
   
   mov ax, [ebx]
   
   ret
ValidateDigitStr   endp



_start:

mainProcess:

   ;get first operand                        
      output prompt1          ;display first prompt to user
      input strInput, 8      ;store user input in a string

~~~~~~~~



everytime i try to run the program it runs through the proc before it is called lower in the program. Sure enough as I walk through win debugger, it walks right through the procedure BEFORE it is called rather than skipping to the _start segment of code....I have another piece of code where this procedure definition works and it skips over it until the procedure is called but this code wont work!!!

any ideas???


This code doesnt do anything yet so that is unimportant, I just want to know why it is running through bits of the procedure call without it even being called
      

herge

Hi theZeroFlag:

where is
end start

Regards herge
// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

theZeroFlag

it is at the end of my code

i just posting a few segments of the starting block

this is the end

   Invoke   ExitProcess,0
   public   _start
   End

theZeroFlag

It is possible to have a conditional jump within a procedure, right? Becuase everytime I add one it wants to jump directly into my procedure block....

i am thoroughly confused.

qWord

Your code should look something like this:



.code

ValidateDigitStr   proc
...
ValidateDigitStr   endp

_start:

...
call ValidateDigitStr
...

invoke ExitProcess,0

end _start   ;declare the program entry point


FPU in a trice: SmplMath
It's that simple!

hutch--

Get rid of the line,


   .stack 100h


In a 32 bit PE file the stack is set as a linker option.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Mark Jones

Some notes:

Quote from: theZeroFlag on October 19, 2008, 08:01:47 PM
assume this begging segment of code
; Just a pedantic note, there is no such thing as a "segment" of any sort in 32-bit code. When the linker fixes up all the code into the final PE executable, it does create a "code" or "text" section for the executable bytes, and a "data" section for the initialized data (and other sections for certain types of data) but all this is bundled inside that executable. Search for "Portable Executable Format" for more details.

   .486
   .model Flat
   ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

   ; this all can be replaced with INCLUDE MASM32RT.INC (makes life easier)

   Include io.h             ;include macros input/output - ASCII to binary conversion
   ; is this something your instructor has provided? normally assembler includes end in ".inc". ".h" files are usually C/C++.
   
   .stack 100h   ; unneccesary in general win32 programming
   
        .data
shortOperand1 WORD ?         ;2 byte operand
shortOperand2 WORD ?         ;2 byte operand
doubleResult DWORD ?         ;4 byte result
; Just a note here, you have declare this as a ".DATA" section, which means it is initialized data (data stored within the executable for use at run-time), and then set the members values equal to "?", which is an uninitialized state. Either set their values to "0", or (better yet) declare the section as ".DATA?", which is for un-initialized data. Uninitialized data is not stored in the final executable (their members are created at run-time.)

.code

ValidateDigitStr   proc   Near32   ; usually not necessary to declare procs as "near" or "far"
   push ebp
   mov ebp, esp
   push ebx                ;preserve ebx register
   push ecx               ;preserve ecx register   
   mov ebx, [ebp+8]   
   mov ax, [ebx]   
   ret ; 3 pushes without balancing the stack - could cause a stack overflow
ValidateDigitStr   endp



_start:      ; why the leading underscore?

mainProcess: ; just a note, mainProcess = _start (it defines the same location, why not just use "_start" ?)

   ;get first operand                        
      output prompt1          ;display first prompt to user
      input strInput, 8      ;store user input in a string
      ; these must be macros. they do not appear to be part of the MASM32 package.

~~~~~~~~

This code doesnt do anything yet so that is unimportant, I just want to know why it is running through bits of the procedure call without it even being called

Unless you have specified in the linker to use "_start" as the entrypoint (or you are using GoASM?) I believe the entrypoint is called "start" and this could cause problems. What are the assemble and link warnings you receive?

The ValidateDigitStr function is executed first because it is immediately after the _start: entrypoint. Unlike a compiler, which would "rearrange" things and prevent this behavior, MASM does not do this. This is by design. Declaring something as a procedure does not mean that it will only be executed when called or invoked -- in fact, the procedure name (ValidateDigitStr) is the same thing ultimately as _start: -- it is a label to an offset, where code resides. So the short answer would be, "jump around" your procedure. But better yet, would be to write main calls or invokes right after "_start:", then exit process. AFTER that, place the procedures. This way, code execution will only branch to the procedures when they are called. i.e.:


; start of myapp
include \masm32\include\masm32rt.inc
myroutine1 PROTO
myroutine2 PROTO

.data?
myvar DD ?   ; just 4 bytes we can use for later

.code
start:
invoke myroutine1           ; do something
mov DWORD PTR [myvar],123h  ; put a value in our DWORD
invoke myroutine2           ; do something else
invoke ExitProcess,0        ; exit gracefully

myroutine1 PROC
; do stuff here...
ret  ; note is is important to RET -- if not, execution will continue into the next procedure!
myroutine1 ENDP

myroutine2 PROC
; do other stuff here...
ret
myroutine2 ENDP

end start


Take a peek at \masm32\help\asmintro.chm and masm32.chm -- they both provide key information needed to write successful code in MASM32. Have fun. :U
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

theZeroFlag

Thanks for the help. I understand everything you have given pointed out.

_start is used so the windbg.exe program I use to debug will find the correct entry point

io.h is a macro provided by Detmer(the author of a book I am learning from), I wondered why it was a .h file considering I normally program in C++

anyway, thanks again.