News:

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

Main Menu

Environment issue? Simple or not so simple?

Started by Nate523, September 13, 2024, 07:03:43 AM

Previous topic - Next topic

Nate523

Well I am hoping that I can get started with MASM someday, but I am having a little snag I think with setting up the environment. Tried to do this basic program from "Microsoft Assembly x64 Programming modern coding for MASM, SSE & AVX" by Mike McGrath

INCLUDELIB kernel32.lib
ExitProcess PROTO
.DATA

.CODE
main PROC

CALL ExitProcess
main ENDP
END

The environment I am trying to do this in is Visual Studio 2022 Express edition, installed the C++ workload, I setup an empty console project, set build dependencies to the MASM option "masm(.targets, .props)", set the linker->advanced properties to "main" for Entry point. Create the file with the .asm extension, and then after typing the previous code build the solution. It builds fine, but when I run I get this:

(process 13440) exited with code -1073741819 (0xc0000005)

And from: https://www.febooti.com/products/automation-workshop/online-help/actions/run-cmd-command/exit-codes/

I am told that specific exit code means I am having a memory access violation, so the program is crashing! Not sure what I was expecting from the program, but later the book has me look at the exit code with echo %errorlevel% and I still get the same exit code. I've also tried compiling, linking, and running in the command prompt using ML64.exe and LINK.exe, and after doing echo %errorlevel% I get the same code.

I suspect that I am not setting up Visual Studio properly, or I have not allowed access to the kernel32.lib or KernelBase.dll in some way because the VS IDE debugger says the violation is related to functions in the KernelBase.dll.

Exception thrown at 0x00007FFACDC82AAA (KernelBase.dll) in Project1.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

I have tried watching 3 videos now that setup similar to the way the book has the IDE, and still get the same results while they get a return code that they put in the RCX register with "mov $78, RCX" which I have also tried to no avail. I usually program in C and C++ so assembly is new, and setting up the environment has always bit me in the past so hoping I am simply missing a step somewhere.

BugCatcher

In 64bit you have to declare the entry point of your program. You can do it manually or as I do, use the default
mainCRTStartup

sinsi

The Win64 ABI requires a few extra things
INCLUDELIB kernel32.lib
ExitProcess PROTO
.DATA

.CODE
main PROC
sub rsp,28h ;<<<< 32 bytes for spill space plus 8 bytes for alignment
CALL ExitProcess
main ENDP
END

If you run it through the debugger, you get the faulting instruction
00007FFC73BE2AAA 0F 28 44 24 40       movaps      xmm0,xmmword ptr [rsp+40h] Without the stack adjustment RSP isn't aligned to 16 but movaps needs 16 byte alignment (the a tells you that the instruction needs alignment).
😁

zedd151

Hmmm. An ExitProcess call without an argument. That means that whatever(?)  happens to be in rcx at the time is considered the exit code? Unless I am missing something.  :tongue:
:azn:

NoCforMe

No, it means that whatever's on the stack will taken to be the exit code. So, garbage in this case.
Assembly language programming should be fun. That's why I do it.

sinsi

Quote from: NoCforMe on September 13, 2024, 02:49:49 PMNo, it means that whatever's on the stack will taken to be the exit code. So, garbage in this case.
No, 64-bit uses RCX for the first arg, not the stack.
😁

zedd151

Quote from: sinsi on September 13, 2024, 03:20:37 PM
Quote from: NoCforMe on September 13, 2024, 02:49:49 PMNo, it means that whatever's on the stack will taken to be the exit code. So, garbage in this case.
No, 64-bit uses RCX for the first arg, not the stack.
Exactly, like I said above.  :biggrin:
:azn:

sinsi

Quote from: zedd151 on September 13, 2024, 03:45:43 PM
Quote from: sinsi on September 13, 2024, 03:20:37 PM
Quote from: NoCforMe on September 13, 2024, 02:49:49 PMNo, it means that whatever's on the stack will taken to be the exit code. So, garbage in this case.
No, 64-bit uses RCX for the first arg, not the stack.
Exactly, like I said above.  :biggrin:
Maybe some people should stick to 32-bit code :badgrin:
😁

zedd151

Quote from: sinsi on September 13, 2024, 04:20:37 PM
Quote from: zedd151 on September 13, 2024, 03:45:43 PM
Quote from: sinsi on September 13, 2024, 03:20:37 PM
Quote from: NoCforMe on September 13, 2024, 02:49:49 PMNo, it means that whatever's on the stack will taken to be the exit code. So, garbage in this case.
No, 64-bit uses RCX for the first arg, not the stack.
Exactly, like I said above.  :biggrin:
Maybe some people should stick to 32-bit code :badgrin:
:biggrin:  :cool:
:azn:

NoCforMe

Assembly language programming should be fun. That's why I do it.


Nate523

Quote from: sinsi on September 13, 2024, 08:23:26 AMThe Win64 ABI requires a few extra things
INCLUDELIB kernel32.lib
ExitProcess PROTO
.DATA

.CODE
main PROC
sub rsp,28h ;<<<< 32 bytes for spill space plus 8 bytes for alignment
CALL ExitProcess
main ENDP
END

If you run it through the debugger, you get the faulting instruction
00007FFC73BE2AAA 0F 28 44 24 40       movaps      xmm0,xmmword ptr [rsp+40h] Without the stack adjustment RSP isn't aligned to 16 but movaps needs 16 byte alignment (the a tells you that the instruction needs alignment).

Thank you this got me going! I also added:
mov RCX, 78

and now I am getting the exit code 78 which ... not knowing exactly what I am doing seems to be in the right direction. I appreciate the help because it means I can continue! Until the next roadblock at least..

I'm still not exactly clear on the reasoning for having to add this though and sounds like I need to read up on alignment and vector interrupts:

sub rsp, 28h

sub is a subtraction instruction, rsp is the general purpose register that holds the address to the top of the stack, and the 28h is a vector interrupt, correct? If I am grasping at least the basics of what you're saying is that the Windows Application Binary Interface (ABI) requires I byte align the address of the top of the stack to 16 bytes, and that somehow (not sure exactly how the subtraction of the address in the rsp by a what the vector interrupt contains accomplishes this) that line of code accomplishes that? Otherwise if I don't do that, data is not aligned and thus memory access violations occur and the program crashes? I guess I'm asking because it seems like I will have to do this for every example in this book that I am using to learn some of this.

NoCforMe

No, not interrupt vectors; you might be thinking of the good old 8088 with its interrupt table in the first 256 doublewords of RAM. It's just a displacement into the stack.
Assembly language programming should be fun. That's why I do it.

Nate523

Quote from: NoCforMe on September 14, 2024, 08:00:31 AMNo, not interrupt vectors; you might be thinking of the good old 8088 with its interrupt table in the first 256 doublewords of RAM. It's just a displacement into the stack.

Maybe that's what I would think if I knew anything about assembly? I have no clue really, thanks for clarifying. I just was searching for what that 28h means and interrupt vectors is what started to come up. Hopefully between the three books and other resources I got for assembly, displacing into the stack will make more sense as I go. For now I guess I will just keep it in my mind that there is a perfectly good reason why I need to do this, I just don't understand it yet :biggrin: It is always interesting when you have to do extra to get example code to work.

NoCforMe

Looks like time for sinsi to explain spill space and all the other memory-layout weirdnesses of the 64-bit ABI ...

Nothing magic about 28H (= 40 decimal). Just a number of DWORDs/QWORDs (not sure which).
Assembly language programming should be fun. That's why I do it.