News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

How to print out values in MASM syntax?

Started by RedSkeleton007, June 27, 2015, 06:54:38 AM

Previous topic - Next topic

RedSkeleton007

Quote from: dedndave on January 25, 2016, 09:17:20 AM
DAYS_OF_WEEK STRUCT
  lpSun LPSTR ? ;what is does lp and LP do?
  lpMon LPSTR ?
  lpTue LPSTR ?
  lpWed LPSTR ?
  lpThu LPSTR ?
  lpFri LPSTR ?
  lpSat LPSTR ?
DAYS_OF_WEEK ENDS

    .DATA
    ALIGN   4 ;what is being aligned by 4 spaces?

dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat> ;what is up with the sz?

szSun BYTE "Sunday",0
szMon BYTE "Monday",0
szTue BYTE "Tuesday",0
szWed BYTE "Wednesday",0
szThu BYTE "Thursday",0
szFri BYTE "Friday",0
szSat BYTE "Saturday",0


My questions for you are commented in your code above.

Quote from: dedndave on January 25, 2016, 09:17:20 AM
now, you can calculate the offset into the "dow" structure using (4*X), where X = 0 to 6
What are you even talking about? Is dow a reserved word? Remember, I'm only finishing chapter 3, so keep it as simple as possible please.

dedndave

#16
  lpSun LPSTR ? ;what is does lp and LP do?

lpSun is just a symbol name, using "Hungarian Notation"
it means that lpSun is a "Long Pointer", which you can tell just by looking at the name
this notation is often used on the MSDN site - so, it's nice to be familiar
(i could have also used lpszSun, meaning it's a long pointer to a zero-terminated string)

https://en.wikipedia.org/wiki/Hungarian_notation

LPSTR is a type - it is defined in windows.inc as

LPSTR TYPEDEF DWORD

meaning it is DWORD size - it stands for "Long Pointer to a STRing"

    .DATA
    ALIGN   4 ;what is being aligned by 4 spaces?

the "dow" structure is aligned to an address that is evenly divisable by 4
accessing dword-sized data is faster when it is 4-aligned

"dow" is defined in the .DATA section as

dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat> ;what is up with the sz?

and finally, "sz" is again Hungarian Notation, meaning "String, Zero-terminated"

dedndave

here's an example of an MSDN page...

https://msdn.microsoft.com/en-us/library/windows/desktop/ms684183%28v=vs.85%29.aspx

the C prototype
DWORD WINAPI LoadModule(
  _In_ LPCSTR lpModuleName,
  _In_ LPVOID lpParameterBlock
);


DWORD WINAPI = returns a DWORD (in EAX), windows API function
_In_ = it's an input argument
LPCSTR = long pointer to a constant string
LPVOID = long pointer to an undescribed type
lpModuleName and lpParameterBlock are symbol names that use Hungarian Notation

RedSkeleton007

Quote from: dedndave on January 25, 2016, 09:17:20 AM
DAYS_OF_WEEK STRUCT
  lpSun LPSTR ?
  lpMon LPSTR ?
  lpTue LPSTR ?
  lpWed LPSTR ?
  lpThu LPSTR ?
  lpFri LPSTR ?
  lpSat LPSTR ?
DAYS_OF_WEEK ENDS

    .DATA
    ALIGN   4

dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat>

szSun BYTE "Sunday",0
szMon BYTE "Monday",0
szTue BYTE "Tuesday",0
szWed BYTE "Wednesday",0
szThu BYTE "Thursday",0
szFri BYTE "Friday",0
szSat BYTE "Saturday",0


now, you can calculate the offset into the "dow" structure using (4*X), where X = 0 to 6

;EAX = 0 to 6

    mov     edx,dow[4*eax]   ;EDX = address
    print    edx


you can certainly do that in a single line, too

    print   dow[4*eax]

if you just want to print a string....

    print   offset szMon

the print macro wants an address

I tried it your way dedndave, but I got some errors that I'm not sure how to fix:

; This program defines symbolic constants for all seven days
; of the week, then demonstrates them by outputting them to
; the screen.

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword

DAYS_OF_WEEK STRUCT
  lpSun LPSTR ? ;error: initializer magnitude too large for specified size
  lpMon LPSTR ?
  lpTue LPSTR ?
  lpWed LPSTR ?
  lpThu LPSTR ?
  lpFri LPSTR ?
  lpSat LPSTR ?
DAYS_OF_WEEK ENDS

.data
;ALIGN   4

     dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat> ;error: structure cannot be instanced

     szSun BYTE "Sunday",0
     szMon BYTE "Monday",0
     szTue BYTE "Tuesday",0
     szWed BYTE "Wednesday",0
     szThu BYTE "Thursday",0
     szFri BYTE "Friday",0
     szSat BYTE "Saturday",0
     
.code
main proc

     ; What's the MASM syntax for outputting values stored in variables?

     mov     edx,dow[4*eax]   ;EDX = address
     print    edx ;error: undefined symbol

invoke ExitProcess,0
main endp
end main

fearless

The structure cannot be instanced error is due to the previous error relating to LPSTR ? ;error: initializer magnitude too large for specified size.

Im guessing you need to include windows.inc in your source file so it knows what LPSTR is. Try this:
.386
.model flat,stdcall
.stack 4096
include windows.inc


or if that doesnt work, you can always change the LPSTR references to DWORD instead, like:
DAYS_OF_WEEK STRUCT
  lpSun DWORD ? ;error: initializer magnitude too large for specified size
  lpMon DWORD ?
  lpTue DWORD ?
  lpWed DWORD ?
  lpThu DWORD ?
  lpFri DWORD ?
  lpSat DWORD ?
DAYS_OF_WEEK ENDS


windows.inc includes the typedef for the LPSTR as (basically seen as the same thing to the assembler, more useful for us humans to understand its a pointer to a string):
LPSTR                       typedef DWORD

dedndave

windows.inc is correct
and - you don't need a .stack statement with a flat model

RedSkeleton007

Quote from: fearless on January 26, 2016, 12:09:49 PM
windows.inc includes the typedef for the LPSTR as (basically seen as the same thing to the assembler, more useful for us humans to understand its a pointer to a string):
LPSTR                       typedef DWORD
We're getting closer ;) Please see the comments in my code:

; This program defines symbolic constants for all seven days
; of the week, then demonstrates them by outputting them to
; the screen.

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword ;what is this line doing?

DAYS_OF_WEEK STRUCT
  lpSun DWORD ?
  lpMon DWORD ?
  lpTue DWORD ?
  lpWed DWORD ?
  lpThu DWORD ?
  lpFri DWORD ?
  lpSat DWORD ?
DAYS_OF_WEEK ENDS

.data
;ALIGN   4

     dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat>

     szSun BYTE "Sunday",0
     szMon BYTE "Monday",0
     szTue BYTE "Tuesday",0
     szWed BYTE "Wednesday",0
     szThu BYTE "Thursday",0
     szFri BYTE "Friday",0
     szSat BYTE "Saturday",0
     
.code
main proc

     ; What's the MASM syntax for outputting values stored in variables?

     mov     edx,dow[4*eax]   ;error: instruction operands must be the same size
     print    edx ;error: initializer magnitude too large for specified size

invoke ExitProcess,0
main endp
end main

Also, why are we putting the STRUCT before the .data directive portion of the code?

dedndave

remove the .stack statement

if operand size is an issue, use a size override

    mov     edx,dword ptr dow.[4*eax]

the error on print doesn't make sense
it could be because of .386, rather than .486 or .586
.386 does not allow some "newer" addressing modes, and some instructions

when we build, even the simplest of programs, we include several INC files and includelib several LIB files
(they take care of most of the API prototypes, like ExitProcess)
to avoid all that typing, we generally place one line at the beginning

    INCLUDE  \masm32\include\masm32rt.inc

it also takes care of the processor, model, and casemap
it's a plain text file (you can open it with NotePad)
have a look at it to see what it adds to the program source

and - structure definitions do not create any code - they merely define a new type, in a way
they do not need to be in an open data/code section

dedndave

#23
give this one a try
;###############################################################################################

        INCLUDE    \Masm32\Include\Masm32rt.inc
        .586

;###############################################################################################

DAYS_OF_WEEK STRUCT
  lpSun DWORD ?
  lpMon DWORD ?
  lpTue DWORD ?
  lpWed DWORD ?
  lpThu DWORD ?
  lpFri DWORD ?
  lpSat DWORD ?
DAYS_OF_WEEK ENDS

;###############################################################################################

        .DATA
        ALIGN   4

dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat>

szSun BYTE "Sunday",0
szMon BYTE "Monday",0
szTue BYTE "Tuesday",0
szWed BYTE "Wednesday",0
szThu BYTE "Thursday",0
szFri BYTE "Friday",0
szSat BYTE "Saturday",0

;***********************************************************************************************

   ;     .DATA?

;###############################################################################################

        .CODE

;***********************************************************************************************

main    PROC

        mov     ebx,7

loop00: mov     eax,7
        sub     eax,ebx
        print   dow.lpSun[4*eax],13,10
        dec     ebx
        jnz     loop00

        inkey
        exit

main    ENDP

;###############################################################################################

        END     main


EDIT: changed it to
        print   dow.lpSun[4*eax],13,10

RedSkeleton007

Quote from: dedndave on January 26, 2016, 10:12:02 PM
when we build, even the simplest of programs, we include several INC files and includelib several LIB files
(they take care of most of the API prototypes, like ExitProcess)
to avoid all that typing, we generally place one line at the beginning
    INCLUDE  \masm32\include\masm32rt.inc
It should be noted that I'm using Kip Irvine's text book:
http://kipirvine.com/asm/
and its resources. I cannot predict what might happen if I tried including both libraries and source into my code. And I'm strongly reluctant to switching to the MASM32 compiler used by the members on these forums, because later on in Irvine's text book, he uses C++ code with inline assembly language in the same source code files. And for someone like me who's more familiar with C++, it will very likely make it easier to understand what's going on with the MASM syntax. Plus, I payed over $500 for Visual Studio Professional 2013!

Also, right now, I'm just trying to accomplish one of the end-of-chapter programming exercises, worded exactly as:

"Write a program that defines symbolic constants for all seven days of the week. Create an array variable that uses the symbols as initializers."

Loops are not introduced until the next chapter. I have not encountered Structs in the book yet. The reason I'm trying so hard to print them out is JUST SO I CAN TEST THE DAMNED THINGS! But since this isn't an easy-peesy Java or C++ Hello World App, is there a better, more simpler way to test MASM assembly code than printing out values?

dedndave

i've been working on an Irvine32.lib and inc that are compatible with masm32
here are my notes...

Quote1) In the Irvine32 library, the "OPTION CaseMap:None" directive is commented out as optional.
   Per Microsoft API documentation, case sensitivity should be observed.
   The Masm32 library is also designed for case sensitive symbols.

2) The POINT structure was defined with members named upper-case "X" and "Y".
   Per Microsoft documentation, these were renamed to lower-case "x" and "y".

3) "GetTextColor" and "SetTextColor" are functions defined in the Irvine32 library.
   They are used to retrieve and set console-mode text color.
   However, pre-existing Microsoft API functions (used for GUI apps) are defined in Gdi32.dll.
   To allow them to co-exist, we use the names "GetConTextColor" and "SetConTextColor".

4) "MsgBox" is a PROC defined in Irvine32, used in a few Irvine32 example programs.
   "MsgBox" is a powerful MACRO defined in Masm32, used in many existing programs.
   The Irvine32 PROC name is changed to "MsgBoxOk".

5) "exit" is a TEXTEQUate (pseudo-macro) defined in Irvine32.
   "exit" is a MACRO defined in Masm32 that allows an optional return code argument.
   The Masm32 macro will perform the same function if no arguments are specified.
   Conditional assembly is used to avoid redefinition in Irvine32.

6) In the Irvine32 SmallWindows.inc file, SetConsoleCursorPosition, SetConsoleScreenBufferSize,
   WriteConsoleOutputCharacter, and WriteConsoleOutputAttribute are all PROTOtyped with COORD arguments.
   While this is technically correct, it does not allow the use of a register in place of a COORD structure.
   A COORD structure has 2 WORD members, that may be replaced with any DWORD sized operand, if PROTOtyped as such.
   The Masm32 library PROTOtypes these functions with DWORD arguments in place of COORD structures.

7) The SetConsoleTextAttribute function is PROTOtyped with a WORD argument. Again, this is technically correct,
   per MSDN documentation. However, arguments are passed on the stack and the stack should always retain DWORD
   alignment in Win32 programming. The Masm32 library has this function PROTOtyped with a DWORD argument.

8- Irvine32 example programs may be modified to be compatible by making a few name changes.
   Fortunately, most Irvine32 examples do not use these symbols:
     MsgBox       -> MsgBoxOk
     GetTextColor -> GetConTextColor
     SetTextColor -> SetConTextColor
     POINT.X,Y    -> POINT.x,y
   Function calls mentioned in 6) and 7), above, may require some modification to match argument size and type.
   Also, all symbol names are now case sensitive. Some modification may be required to match case.

TWell

#26
As you have Visual Studio, you can watch registers in there ;)
.386
.model flat,stdcall
ExitProcess proto dwExitCode:dword
printf proto C :dword, :vararg
includelib msvcrt.lib

DAYS_OF_WEEK STRUCT
  lpSun DWORD ?
  lpMon DWORD ?
  lpTue DWORD ?
  lpWed DWORD ?
  lpThu DWORD ?
  lpFri DWORD ?
  lpSat DWORD ?
DAYS_OF_WEEK ENDS

.data
    dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat>
    szSun BYTE "Sunday",0
    szMon BYTE "Monday",0
    szTue BYTE "Tuesday",0
    szWed BYTE "Wednesday",0
    szThu BYTE "Thursday",0
    szFri BYTE "Friday",0
    szSat BYTE "Saturday",0
    szCrLf db 13,10,0

.code
main proc
    mov    esi, offset dow ;[0] ; point to pointer array
    mov    ebx, 7 ; counter
@@:
    mov    edi, dword ptr esi  ; point to string
    invoke printf, edi         ; print string
    invoke printf, addr szCrLf ; linefeed
    add    esi, 4 ; move to next dword pointer
    dec    ebx    ; count down
    jnz    @B     ; until zero
    invoke ExitProcess,0
main endp
end main
EDIT:
Beware: use msvcrt.lib from masm32 package, not those sad msvc versions for cpp :(

RedSkeleton007

Quote from: dedndave on January 26, 2016, 10:23:37 PM
give this one a try
;##################################################

        INCLUDE    \Masm32\Include\Masm32rt.inc
        .586

;#####################################################

DAYS_OF_WEEK STRUCT
  lpSun DWORD ?
  lpMon DWORD ?
  lpTue DWORD ?
  lpWed DWORD ?
  lpThu DWORD ?
  lpFri DWORD ?
  lpSat DWORD ?
DAYS_OF_WEEK ENDS

;##################################################

        .DATA
        ALIGN   4

dow DAYS_OF_WEEK <szSun,szMon,szTue,szWed,szThu,szFri,szSat>

szSun BYTE "Sunday",0
szMon BYTE "Monday",0
szTue BYTE "Tuesday",0
szWed BYTE "Wednesday",0
szThu BYTE "Thursday",0
szFri BYTE "Friday",0
szSat BYTE "Saturday",0

;*******************************************************************

   ;     .DATA?

;######################################################
        .CODE

;******************************************************************

main    PROC

        mov     ebx,7

loop00: mov     eax,7
        sub     eax,ebx
        print   dow.lpSun[4*eax],13,10
        dec     ebx
        jnz     loop00

        inkey
        exit

main    ENDP

;#################################################

        END     main


I tried running this version of dedndave's code attempts in the MASM32 Application (apparently, I have already installed it before, and forgot about it). However, when I try to run an .asm file, a copy of that .asm file automatically opens up in Visual Studio as a standalone text file, along with two other windows (see attached picture). I recon it's not supposed to do that? How do I get Visual Studio to shut up and mind it's own business?

I can't seem to find the MASM32 Application manual anywhere in the MASM32 folder either. Where is it? My gut tells me that it would be easier for me to learn MASM (and easier for you guys to keep helping me) if I just use MASM32 instead of Visual Studio to learn MASM). Is that a good attitude to have, or should I stick with Irvine and Visual Studio? If MASM32 is the better choice, I have two little favors to ask:

1.) A template for Irvine's example programs looks like this:

; Program template

.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword

.data
; declare variables here
.code
main proc
; write your code here

invoke ExitProcess,0
main endp
end main

Can you edit that code into what an MASM32 template is supposed to have?

2.)Make me a simple .asm file that, when it runs, will output "Hello World"

Thanks in advance.

GoneFishing

Simple console "Hello World" is integrated into QEDITOR:
Menu Code -> Fast insert console template -> save it in right place (inside masm32 folder) -> Project -> Console build -> Project -> Run

dedndave

let's start with visual studio opening asm files
i think you are refering to "File Associations" (a good google term - you can add "windows")
you should be able to right-click on an asm file, then "Open With"
(if that doesn't work, try shft-right-click)
when you do that, you will be given a choice to select from programs
and, when you do that, there is a little check box at the bottom of the dialog if you wish to change it
i hate to give advice to change a file association, because it may cause problems later on
but - right-clicking will at least allow you to select a different program