The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: TBRANSO1 on November 30, 2018, 04:24:05 AM

Title: Help with console output
Post by: TBRANSO1 on November 30, 2018, 04:24:05 AM
I am still learning to use MASM.  I am using the 64 bit VS version.  I have designed a couple of functions to read from and print to console

BTW I am calling the MASM functions with the proper extern "C" statements, from a C++ main for now.

I was wondering if someone could help with the output.

(FORGIVE ME, I WANTED TO INSERT AN IMAGE, BUT CAN'T FIGURE OUT HOW)
COMMANDLINE OUTPUT>
Hello, Tom, from VS2017 MASM64 - prints first
Hi there, VS2017 MASM64, thank you! - I enter some input
Hi there, VS2017 MASM        k you! - echos input to screen

My issue is that if I wrote less than the number of bytes where the part where it skips, it prints normally, it does this when it is more than 20 or so characters.  I have allocated a buffersize of 64 bytes. so it should be fine.

I am using WinAPI, ReadFile and WriteFile, here is my code:
; *************************************************************************
; MASM32 proto types for Win32 functions and structures
; ************************************************************************* 
;include c:\masm32\include\kernel32.inc
;include c:\masm32\include\masm32.inc

; *************************************************************************
; MASM32 object libraries
; ************************************************************************* 
includelib c:\masm32\lib\masm32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\user32.lib
includelib Kernel32.lib

extern MessageBoxA: proc
extern CreateThread: proc
extern WriteFile: proc
extern ReadFile: proc
extern GetStdHandle: proc

MAX_SIZE equ 10
STR_LEN equ sizeof hello
BUF_LEN equ 40h
STD_INPUT_HANDLE equ -10
STD_OUTPUT_HANDLE equ -11
INVALID_HANDLE_VALUE equ -1

.data
mybyte1 db 4
mybyte2 db 1
mutex dword 0 ; mutex
BytesWritten dword 0
BytesToRead dword 0
hello db "Hello, Tom, from VS2017 MASM64", 13, 10
shit db "SHITHEAD!", 0
name_prompt db "Please type your name: %c", 10, 0
out_msg db "Your name in capitals is ", 0

.data?
array db ?
mynum qword ?
num dword ?
shifter qword ?
hFile qword ?
my_name db ?

.code

PrintString MACRO string, size, readLen
    ; https://blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735
    sub rsp, 40                 ; Shadow space (4 * 8) & 1 parameter (8 bytes)
    ; https://docs.microsoft.com/en-us/cpp/build/stack-allocation
    and spl, -16                ; Align to 16

    ; https://msdn.microsoft.com/library/windows/desktop/ms683231.aspx
    mov ecx, STD_OUTPUT_HANDLE  ; DWORD nStdHandle = STD_OUTPUT_HANDLE
    call GetStdHandle           ; Call WinApi
    mov hFile, rax              ; Save returned handle

    mov bl, 1 ; Set ZF = 1

    ; https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-writefile
; BOOL WINAPI WriteFile(
    mov rcx, hFile              ; HANDLE        hFile (here: Stdout)
    lea rdx, string             ; LPCVOID       lpBuffer
    lea r9, readLen         ; LPDWORD       lpNumberOfBytesWritten
    mov r8d, size ; DWORD         nNumberOfBytesToWrite
    mov qword ptr [rsp+32], 0   ; LPOVERLAPPED  lpOverlapped = NULL
    call WriteFile              ; Call WinAPI
; );
   test bl, al ; test ZF for errors
   mov readLen, 0 ; Zero out the variable for reuse

   ; https://msdn.microsoft.com/library/windows/desktop/ms682658.aspx
   xor rcx, rcx                ; Set RCX / Close HANDLE
   add rsp, 40
   ret
endm

getCmdLineInput proc
; https://blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735
        sub rsp, 40                 ; Shadow space (4 * 8) & 1 parameter (8 bytes)
    ; https://docs.microsoft.com/en-us/cpp/build/stack-allocation
        and spl, -16                ; Align to 16

       mov ecx, STD_INPUT_HANDLE   ; DWORD nStdHandle = STD_INPUT_HANDLE
       call GetStdHandle           ; Call WinApi
       mov hFile, rax              ; Save returned handle

       mov bl, 1 ; Set ZF = 1

; https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-readfile
; BOOL ReadFile(
mov rcx, hFile ;   HANDLE       hFile,
lea rdx, array ;   LPVOID       lpBuffer,
mov r8d, BUF_LEN ;   DWORD        nNumberOfBytesToRead,
lea r9, BytesWritten ;   LPDWORD      lpNumberOfBytesRead,
mov qword ptr [rsp+32], 0 ;   LPOVERLAPPED lpOverlapped
call ReadFile ; Call WinAPI
; );

test bl, al ; test ZF for errors

        xor rcx, rcx                ; Set RCX / Close HANDLE
add rsp, 40

PrintString array, BytesWritten, BytesToRead

ret
getCmdLineInput endp


I have a question about macros... do you typically put in the full code with the ret?

I haven't finished error checking, as for testing for errors, like invalidHandle (-1)... is that correct using the test, then a jz or jne?

Thanks

PS: I realized after I wrote this, that it may be in the wrong forum... Admin, please feel free to put it where it goes.
Title: Re: Help with console output
Post by: aw27 on November 30, 2018, 05:08:18 AM
Sorry, I landed here from Mars, so my question may sound weird.

What is VS2017 MASM64? Why are you mixing 32-bit libraries with 64-bit code? Where is the entry point of your program?
Title: Re: Help with console output
Post by: TBRANSO1 on November 30, 2018, 05:51:37 AM
Quote from: AW on November 30, 2018, 05:08:18 AM
What is VS2017 MASM64? Why are you mixing 32-bit libraries with 64-bit code? Where is the entry point of your program?


Visual Studio 2017 masm64 just refers to using masm 64bit with ML64.exe compiler.  Entry is mentioned above in a C++ main. I am using 64 bit, b/c I can, and I also am creating algos to crunch large numbers.
Title: Re: Help with console output
Post by: aw27 on November 30, 2018, 06:37:02 AM
Looks interesting your logic as well as omitting part of the answers. You did not explain the reason for 32-bit libraries.
Btw, a macro is not a function, what the hell makes you think it is something needing a ret?
Title: Re: Help with console output
Post by: hutch-- on November 30, 2018, 08:39:29 AM
You are mixing 32 and 64 bit code which will never work as the two OS versions have different architecture. The code you posted is basically 32 bit code and you would build that with the 32 bit version of MASM, ML.EXE.

> extern MessageBoxA: proc

This type of prototyping would almost work in 64 bit but in 32 bit you must construct the prototypes differently.

MessageBox PROTO :DWORD,:DWORD,:DWORD,:DWORD

What is recommended is you use the supplied include files for 32 bit MASM code unless you want to write your own set if you have a couple of years to spend doing it.

Have a look at the "masm32rt.inc" file for 32 bit as it saves you from having to write prototypes for API code. In 32 bit you will have to write your own prototypes for your own procedures.

Now 64 bit MASM is a really different animal, its designed as a professional tool only and is particularly terse with any errors. It does not use the 32 bit version of prototyping and it does not check argument types or argument counts. On the bright side it frees you from endless prototyping which improves your coding speed once you are used to it.

The 64 bit version has its own libraries, include files, macro file and main header file "masm64rt.inc" and you must use them all together as they are written to work with each other.

This is how simple it is to create a console app. It is a standard template in the 64 bit version.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    USING r12

    SaveRegs

    conout "Howdy, your new console template here.",lf,lf

    waitkey
    RestoreRegs
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Help with console output
Post by: TimoVJL on November 30, 2018, 06:28:07 PM
remove these unnessary lines; *************************************************************************
; MASM32 proto types for Win32 functions and structures
; *************************************************************************
;include c:\masm32\include\kernel32.inc
;include c:\masm32\include\masm32.inc

; *************************************************************************
; MASM32 object libraries
; *************************************************************************
includelib c:\masm32\lib\masm32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\user32.lib
includelib Kernel32.lib

extern MessageBoxA: proc
extern CreateThread: proc
make input buffer larger.data?
array db BUF_LEN dup(?)
and put at endend
Title: Re: Help with console output
Post by: aw27 on November 30, 2018, 08:42:36 PM
This is an example of mixing C++ and MASM, reusing as much as possible what this user dropped here.

C++ :


#include "stdio.h"
#include "conio.h"

extern "C"
{
void getCmdLineInput();
char helloMsg[];
}

int main()
{
printf("%s\n",helloMsg);
getCmdLineInput();
printf("Done! Press any key to exit.\n");
_getch();
return 0;
}


MASM:

STD_INPUT_HANDLE equ -10
STD_OUTPUT_HANDLE equ -11
BUF_LEN equ 80h
HANDLE typedef PTR VOID

extern GetStdHandle: proc
extern ReadFile: proc
extern CloseHandle : proc
extern WriteFile : proc

PrintString proto string : PTR, _size : DWORD, writeLenPtr : PTR

.data
helloMsg db "Hello, Tom, from VS2017 MASM64",0

.data?
BytesWritten dword ?
BytesRead dword ?
hFileRead HANDLE ?
hFileWrite HANDLE ?
array db BUF_LEN dup(?)

public helloMsg

.code

getCmdLineInput proc
sub rsp, 28h
mov ecx, STD_INPUT_HANDLE
call GetStdHandle 
mov hFileRead, rax

mov rcx, hFileRead
lea rdx, array
mov r8d, BUF_LEN
lea r9, BytesRead
mov qword ptr [rsp+20h], 0
call ReadFile
cmp eax, 0
jz @exit
lea rcx, array
mov edx, BytesRead
lea r8, BytesWritten
call PrintString
@exit:
add rsp, 28h
ret
getCmdLineInput endp


PrintString proc string : PTR, _size : DWORD, writeLenPtr : PTR
sub rsp, 30h
mov string, rcx
mov _size, edx
mov writeLenPtr, r8

mov ecx, STD_OUTPUT_HANDLE
call GetStdHandle
mov hFileWrite, rax

mov rcx, hFileWrite
mov rdx, string
mov r8d, _size
mov r9, writeLenPtr
mov qword ptr [rsp+20h], 0
call WriteFile

ret
PrintString endp

end


Test Output:
Hello, Tom, from VS2017 MASM64
Visual Studio 2017 masm64 just refers to using masm 64bit with ML64.exe compiler
Visual Studio 2017 masm64 just refers to using masm 64bit with ML64.exe compiler
Done! Press any key to exit.


I attach the built .exe but don't attach the project file because everybody can do that  :t



Title: Re: Help with console output
Post by: BugCatcher on December 01, 2018, 02:47:12 AM
You need to study what macros are for. Study the masm tutorials that have macros declared in them.
Title: Re: Help with console output
Post by: TBRANSO1 on December 01, 2018, 01:01:05 PM
Alright, thanks for the input, everyone.  I am still a learner.  I had read about macros in an assembly textbook, but it didn't give a lot of examples, so I wasn't really sure how to use them, just practicing.

I will work on getting the masm64 libraries installed.

I use Microsoft VS Code or VS Studio as the IDE for a lot of languages.  I use Python(VS Studio and PyCharm), Ruby(RubyCharm), Java (Eclispe), Elixir, Rust, C, C++, and more.  I got a taste for assembly in school and enjoy it.  I am now in a graduate program. I had done simple stuff with assembly, either with Intel or ATT syntax, but am ready to conquer more complex stuff.  Sometimes, when coding in OOP languages, my head gets cloudy with all the indirection and abstraction.  I use assembly as a centering force, since it's more on the metal... I think that it provides a nice distraction and more visual, direct presentation of code. I get excited to move stuff around registers and when it works, more excited.

I guess that this begs the question: what are your opinions on OOP languages?  Personally, I enjoy them, but find them frustrating sometimes when trying to read across what seems 100 different indirection calls trying to track down stuff.  Stuff is buried in stuff.. and sometimes I think to myself, that some of the code could have simply been solved with a few lines of C or assembly???

Anyways, I am just trying to prepare the IDE programming environment for more serious stuff.

Title: Re: Help with console output
Post by: TBRANSO1 on December 01, 2018, 01:06:48 PM
Quote from: AW on November 30, 2018, 08:42:36 PM
Test Output:
Hello, Tom, from VS2017 MASM64
Visual Studio 2017 masm64 just refers to using masm 64bit with ML64.exe compiler
Visual Studio 2017 masm64 just refers to using masm 64bit with ML64.exe compiler
Done! Press any key to exit.


I attach the built .exe but don't attach the project file because everybody can do that  :t

@AW

I see that you removed what I thought was a required stack alignment.  I am still learning, I read on MSDN that it was required at the entry for 64 bit, and found that bit of code of "mov spl, -16" on OS.  I don't know the difference.  https://docs.microsoft.com/en-us/cpp/build/alloca?view=vs-2017. I guess that I am clueless on when and how to use this part?

Thank you, AW
Title: Re: Help with console output
Post by: aw27 on December 01, 2018, 01:53:21 PM
I didn't skip the stack alignment requirement. I know it is aligned so don't need to do anything else. In cases where we use a few local variables we may be a bit lost in the end how the alignment will be after that, so doing and rsp, -16 makes a blind alignment.
Don't excuse yourself invoking that your talent is for other programming flavours. You are disorganized and without clear concepts, this will surface in any other programming variation.

PS: In spite of my speech  :badgrin: there was a stack misalignment in my code, which I fixed.
I have also done some optimizations to reduce the file size to only 3072 bytes.
Title: Re: Help with console output
Post by: felipe on December 02, 2018, 01:12:16 AM
What i think of java is: "If you need a virtual machine to program, you better buy a toy pc and stay away from real hardware..."  :lol:... :badgrin:
Title: Re: Help with console output
Post by: TBRANSO1 on December 02, 2018, 03:04:48 PM
Quote from: AW on December 01, 2018, 01:53:21 PM
I didn't skip the stack alignment requirement. I know it is aligned so don't need to do anything else. In cases where we use a few local variables we may be a bit lost in the end how the alignment will be after that, so doing and rsp, -16 makes a blind alignment.
Don't excuse yourself invoking that your talent is for other programming flavours. You are disorganized and without clear concepts, this will surface in any other programming variation.

PS: In spite of my speech  :badgrin: there was a stack misalignment in my code, which I fixed.
I have also done some optimizations to reduce the file size to only 3072 bytes.

I made the previous adjustments, and I think there was one different thing, but it worked as expected.

I think that I see that you changed the 28h to 30h in the PrintString proc, was there anything else?

I think that this is what I need to understand better is proper stack alignment or procedures, how much to subtract entering any function.  I also have some difficulty determining where parameters are relative to the base and stack pointer.  It's kind of hunt and peck right now... kind of like, let's see if its 4 or 8 or 12 bytes above... oops, nope segmentation fault, then maybe it's below... lol. I'm sure it will get easier.  I need to actually draw a stack on paper and be more accurate in planning... things obviously that don't need to be done with using a higher level language.


I don't mind Java, C# and whatnot, it's kind of planned and canned though... just use a library and code the way Java or C# tells you.  C obviously has it's syntacical rules, but I like the closeness and sometimes the creativity to things.  Ruby or Python are so close, and Ruby is funny since it's sugary sweet with so much syntactic sugar.  Although looking at Ruby's metaprogramming could make you pull your hair out.  I think how many ways can you put lipstick on a for or while statement in the Enumeration class.  It has adopted so many techniques from other languages that I see Java, C#, C++, C, Python, Rust, Go, you name it in the language.  It's only an observation, I love the language as it was my first love. Ha ha.



Title: Re: Help with console output
Post by: aw27 on December 02, 2018, 06:32:08 PM
Quote
I think that I see that you changed the 28h to 30h in the PrintString proc, was there anything else?

This is very easy and at the same time very difficult to internalize (some people take years and most never do). This is the reason you find people saying that x64 is not worthwhile when the true reason is that they are not able to internalize the stack alignment.
There are 2 parts to consider, the x64 Windows ABI part and the MASM part. I assume you already know the x64 ABI part.
The MASM part is easy as well:
1) If the assembler sees a function without parameters and/or local variables it assumes (wrongly or not) it is a leaf function and will not build an rbp based frame. In this case, if you subtract a value to the stack pointer in the prologue you must add it in the epilogue, otherwise the function will crash.
2) If the assembler sees a function with parameters and/or local variables, it has a default prologue and epilogue for it.
This is the case of our PrintString function. In this case it automatically makes an rbp based frame, which happens to align the stack to 16 bytes, since it makes a push. The default epilogue uses the leave instruction before ret, so we don't need to bother about restoring the stack with add rsp, xxx.
And this is all you need to know.
Of course, I did sub rsp, 30h in PrintString because WriteFile has 5 parameters, otherwise (with 4 or less) sub rsp, 20h would be enough to keep the alignment.

Title: Re: Help with console output
Post by: hutch-- on December 02, 2018, 09:22:26 PM
Having read these posts, now you know why I wrote matching prologues and epilogues so that you are free of the guesswork to balance the stack. ML64 is by no means a friendly tool but if you get it right, there is little that you cannot do.
Title: Re: Help with console output
Post by: aw27 on December 02, 2018, 11:36:04 PM
Quote from: hutch-- on December 02, 2018, 09:22:26 PM
Having read these posts, now you know why I wrote matching prologues and epilogues so that you are free of the guesswork to balance the stack. ML64 is by no means a friendly tool but if you get it right, there is little that you cannot do.

Great work  :t. Another alternative is to use a more friendly assembler like UASM.
Title: Re: Help with console output
Post by: hutch-- on December 03, 2018, 12:31:24 AM
Depends if you need someone to hold your hot little hand, ML64 does not, its a professional tool that will bite you on the hand instead.  :P
Title: Re: Help with console output
Post by: TBRANSO1 on December 03, 2018, 01:37:19 AM
Quote from: hutch-- on December 02, 2018, 09:22:26 PM
Having read these posts, now you know why I wrote matching prologues and epilogues so that you are free of the guesswork to balance the stack. ML64 is by no means a friendly tool but if you get it right, there is little that you cannot do.

I understand completely.  As I poked around the files in the SDK, I see all the work that has been done.

I am getting my feet wet.  I am also the type of person that likes to peek underneath the hood and see how things are made.  I also like to attempt things on my own at first as I learn.  Now that you have explain things about the 64 bit version, I will probably go back to using the 32 bit compiler.  I don't have any reason to use 64 bit, except I wanted to see if I could do large numbers, as I had an algorithm that I wanted to test.  It worked out and I got my large numbers.

I guess that I do have a project in mind.  Eventually I would like to get 128 bit size numbers, perhaps even up to 256 bit.  I understand that there is a lot of prep work involved with specific x... or y... registers.  Any references out there to help get me going on this?  Even if its just to calculate Fibonacci of 1000! in assembly.

I am still young in my programming career path, and I realize that I enjoy programming more with embedded systems than making popular UI apps with the latest and greatest framework for Javascript.  As I mentioned that I am in a graduate program, so I am heading towards some specialization.  I just got started, so far it's towards distributed peer to peer systems, decentralized applications, cryptography.  Now, you guys can understand my curiosity.

Programming is my third career path in life.  My first career was as a Russian linguist - Intelligence  expert in the Army and then at the State Department leading up to the end of the cold war and 9/11.  Then, I became a business man, now the wife runs our businesses - she's better at it than I was... lol, she's a natural, born, caring leader with firm convictions and great financial accumen. I was too rough on people, good with numbers, however. I am going back to that type of analytical work that I love.




Title: Re: Help with console output
Post by: hutch-- on December 03, 2018, 02:55:59 AM
Don't give up on 64 bit, its the future. 32 bit is reliable and well understood and it can do many useful things but its running out of puff as the tasks get bigger and will need to be faster. Having 16 integer registers is a genuine blessing and it changes the style of code that you write, proc entry and exit is faster as you don't normally use the stack in 64 bit. At its lowest level it is a bit more complicated due to the calling convention but it is efficient and fast due to that difference.
Title: Re: Help with console output
Post by: aw27 on December 03, 2018, 03:14:02 AM
Here when we make an effort to teach someone something and he backs off in the end, we say that have been wasting our Latin.  :(
Title: Re: Help with console output
Post by: TBRANSO1 on December 03, 2018, 07:17:11 AM
Quote from: hutch-- on December 03, 2018, 02:55:59 AM
Don't give up on 64 bit, its the future.

Nah.. I won't.
Title: Re: Help with console output
Post by: TBRANSO1 on December 04, 2018, 10:59:03 AM
@AW

You know what I realized.  I had saved a link to a codeproject article x64 about stack alignment. Of course, I didn't understand everything, but when I made a mental connection to the website link... I realized that it is you, who wrote the article.  I poked around your site.  Did you write those programs in assembly? Nice work. Wow is all I can say. I guess that I can't pull the wool over your eyes.
Title: Re: Help with console output
Post by: aw27 on December 04, 2018, 05:36:47 PM
A few basic things are really difficult when done in ASM, for example access to WMI functionality.
So, I don't do full blown programs in Assembly Language, just insert a little module here a little module there when I feel it will make a difference for the end user. For example, once I a made a memory move ASM module because it does make a noticeable difference.

In my website I have programs made in Delphi XE2 (the last one I purchased), C++/Cli and C#. My favorite is Delphi because is a good compromise between RAD, performance and access to low level. Users don't care and never ask about the programming language used to cook the program, they are like clients in a restaurant, what matters is the taste of the food.