Why am I having to rebuild an unchanged project?
Asked Answered
P

1

7

I have the following MASM code:

.386
.model flat, stdcall
option casemap :none

include \masm32\include\masm32rt.inc

.data
    NewLine db  13, 10, 0
.code

LibMain proc instance:dword,reason:dword,unused:dword 
    mov     eax, 1
    ret
LibMain endp

PrintMess proc
    print "Printed from assembly"
    invoke StdOut, addr NewLine
    ret
PrintMess endp

TestReturn proc number:dword
    mov     eax, number
    ret
TestReturn endp

End LibMain

With a simple .def file:

LIBRARY MyLib
EXPORTS PrintMess
EXPORTS TestReturn

And I'm calling PrintMess and TestReturn from C# as such:

[DllImport("MyLib")]
static extern void PrintMess();

[DllImport("MyLib")]
static extern int TestReturn(int num);

static void Main(string[] args) {
    Console.WriteLine("Printed from C#");

    PrintMess();

    int value = TestReturn(30);
    Console.WriteLine("Returned: " + value);

    Console.ReadKey(true);
}

The very first time I ran it, it paused at Console.ReadKey(true) and I get the expected output:

Printed from C#
Printed from assembly
Returned: 30

If I then make a change in my C# project, say TestReturn(30) changed to TestReturn(50) then it behaves strangely. The program terminates without error and does not pause on Console.ReadKey(true) (it seems it doesn't even make it to that line) and this is my output:

Printed from C#
Printed from assembly

I have to rebuild the assembly project. Specifically I have to REbuild, if I do another regular build, the program continues to misbehave. When I do rebuild, the output and behavior returns to normal and reflects the number change in the output. My guess is that something is different between Build and Rebuild that's partially breaking the DLL.

Why do I have to rebuild and how I can I set it up so I don't have to?

Pistole answered 18/12, 2012 at 19:26 Comment(7)
+1 for a question with assembly language in it. No idea by the way.Kobold
Could it be an exception being thrown? Have you tried turning on exceptions while debugging?Convoluted
I'm debugging in visual studio and in getting to this point I was throwing exceptions (doing things wrong returning a value from assembly that has since been fixed) but no exceptions are being thrown now.Pistole
This code corrupts the stack. You will need to learn about calling conventions. Covered well in any decent book about x86 assembly.Alysaalyse
This code, as posted above, does not have the same issues I was hounded with in early development that the comment above yours describes. Unless you see a particular problem with calling conventions, I don't think it's the code, I think it's the configuration of environment. Given the instructions I specify above, nothing related to calling conventions changes.Pistole
You are right. I was wrong.Deterge
There is something getting corrupted after the first run. Rebuild = Clean + Build; i.e. the libraries are replaced by new ones.. while only Build doesnt do a clean..Retriever
M
2

@HansPassant is most probably correct but does not explain why you have to rebuild. @jacobaloysious is close.

VS is using what is called "hosting process" to ease and isolate debugging. when you debug test.exe from VS, in fact you are actually debugging test.vshost.exe, which loads your exe. host executable is not unloaded when you stop debugging, so your real executable. when you build your code without changing anything VS actually only does nothing but to check if files are up-to-date. VS thinks, if files are not changed, then there is no need to reload hosting process. if you rebuild, even if you have changed no code, you real executable is updated and this forces host process to be terminated and to be reloaded, along with your real executable.

I think, this process actually for speeding up start-up of debugging by preloading assembly code. you may try turning off "Enable the Visual Studio hosting process" in project properties. After that, you should be seeing you project working as expected.

Before you move further, realize that @HansPassant is correct and you have a corrupted stack, and as time goes by you project will fail in unexpected ways at unexpected times in most unpleasant ways possible. In most cases you application will throw exceptions that has no meaning, and in some cases you application will just vanish.

Mather answered 12/6, 2013 at 7:47 Comment(2)
This is my first time to write assembly that's called from outside assembly. This project is a learning experience and I'm finding resources are slim. How am I corrupting the stack? I've been reading about disabling the prologue and the epilogue and doing them myself, but no difference. What would be the proper way to handle the stack?Pistole
In fact, I have little knowledge about the subject since I'm terrible at assembly. While writing my answer I also tried to answer that question by making a simple dll that exports a function and disassembling it. but MS compiler creates so much assembler code so that was unusable for me. try compiling for x86 instead of MSIL, try messing around with DllImport parameters. try calling your code from a c console application.Mather

© 2022 - 2024 — McMap. All rights reserved.