'printf' function and 'proc' directive behaving weird in ml64(masm x64)?

161 Views Asked by At
;this file -> test1.asm

includelib msvcrt.lib
includelib legacy_stdio_definitions.lib

extern _CRT_INIT: proc     ;custom entrypoint needs c-runtime to be initialised by the programmer.
extern printf: proc
extern ExitProcess: proc

.data
    msg db "hello world!", 13, 10, 0

.code
fun proc 
    sub rsp, 32          ;for shadow space
    call _CRT_INIT       ;called _CRT_INIT because I have my own entry point named "fun"
    lea rcx,msg
    call printf
    add rsp, 32
    call ExitProcess
fun endp
end

commandline for assembler: ml64 /nologo /c test1.asm

commandline for linker: link /entry:fun /subsystem:console test1.obj

This standalone assembly program seems to be working fine. But doing some changes(mentioned below) make the program crash.

1st change -> according to this link both libcmt.lib and msvcrt.lib statically links the native CRT startup (ie both can be used to call _CRT_INIT) into my code. The difference is msvcrt.lib is used with dll. As I don't have any dll I considered using libcmt.lib in place of msvcrt.lib but then the program crashes. Considering there is only printf function associated, that concludes printf function breaks the program. But why?

2nd change -> Now I tried calling this fun() function from a simple .C file. For that I made the necessary changes.

;this file -> test1.asm

;not including any libraries. linking the .c file make the libraries link too because that is in my libpath environment variable

;extern _CRT_INIT: proc    ;no need of _CRT_INIT because now mainCRTStartup() will be the entrypoint and .c file will take care of initializing the c-runtime
extern printf: proc
;extern ExitProcess: proc  ;no need of exitprocess. Instead i'm using ret instruction because I'm calling fun() from .c file.

.data
    msg db "hello world!", 13, 10, 0

.code
fun proc c               ;even if I replace 'c' with something like "abed" the program works. but if I dont give anything after proc then the program crashes.
    sub rsp, 32          ;for shadow space
    lea rcx,msg
    call printf
    add rsp, 32
    ret
fun endp
end
//this file -> test2.c
#include <stdio.h>
#include <conio.h>
void fun();    //in C no need of extern keyword. extern is needed in c++
int main()
{
   fun();
   getch();
}

commandline for assembler: ml64 /nologo /c test1.asm

commandline for compiler: cl /nologo /c test2.c

commandline for linker: link test1.obj test2.obj

In the previous working example (ie. with msvcrt.lib) I don't have to give any suffixes after 'proc' directive. But in this case when I am calling 'fun' as a function from my C file I need to give anything like 'a'/'b'/combination('abcd') after 'proc' directive and only then the program works. If I don't give anything after 'proc' the program crashes. According to official MSDN documentation proc directive also accept language type. Even so wrong/random 'language type name' ie. any word seem to work. But how?

I tried many things like changing the libraries, using different version of printf (like vfprintf) and tried assigning more shadow space also googled much but unable to find any answer.

0

There are 0 best solutions below