DOS Interrupt in masm x86 build failure

I was just starting to learn some x86 builds on win32, and I used masm with visual studio 2008 using the custom build rule that comes with the idea for .asm files. I'm trying to use a DOS interrupt to print to the console, but instead I get the message: "Unhandled exception at 0x00401004 in ASMTest.exe: 0xC0000005: reading location violation 0xffffffff." on the 8th line. I am trying to output a single ascii 'A' character (41h) Here is the masm code:

.386 .MODEL flat, stdcall .CODE start: mov dl, 41h mov ah, 2 int 21h ret end start 

When I use debug.exe and use the "a" command to enter all the .CODE instructions and run it ("g"), it works fine.

Can someone enlighten me on how to use DOS interrupt correctly? Thanks!

EDIT: when programming on win32 Managu it is correct that instead of using a DOS interrupt, you should use a windows api call like WriteConsoleA. This has been a useful resource. If someone is looking for code for this (like me), here it is:

 .386 .MODEL flat, stdcall ; Windows API prototypes GetStdHandle proto :dword WriteConsoleA proto :dword, :dword, :dword, :dword, :dword ExitProcess proto :dword STD_OUTPUT_HANDLE equ -11 .DATA HelloWorldString db "hello, world", 10, 0 .CODE strlen proc asciiData:dword ; EAX used as count, EBX as ascii char pointer, EDX (DL) as ascii char mov eax, -1 mov ebx, asciiData mov edx, 0 BeginLoop: inc eax ; ++count (init is -1) mov dl, [ebx] ; *dl = *asciiptr inc ebx ; ++asciiptr cmp dl, 0 ; if (*dl == '\0') jne BeginLoop ; Goto the beginning of loop ret strlen endp main proc invoke GetStdHandle, STD_OUTPUT_HANDLE mov ecx, eax invoke strlen, addr HelloWorldString invoke WriteConsoleA, ecx, addr HelloWorldString, eax, 0, 0 ret main endp end 

(Set the main entry point)

+3
assembly x86 masm
source share
3 answers

When you use debug.exe to enter this code, you are building a 16-bit (8086 architecture, "real mode") dos program. The selected semantics are true for such a program. However, when you compile the program that you received here with MASM and then link it, you are trying to create a 32-bit (i386-architecture, "protected mode") Windows program. I could be wrong, but I do not think that you can legally even call int 21h in the latter case.

+3
source share

Perhaps this is due to your ret statement. Where are you coming back from? I think this is an unknown place in memory.

Instead, try using int 20h. It will come out gracefully.

It works in debugging (possibly) because it is a more "managed" environment.

0
source share

If we run the 16-bit DOS application - *. com, then DOS will populate the operation code for the instruction "int 20" inside our PSP with offset 0, and the extra DOS pushes the word with zero on our stack before DOS allows us to execute the application. Therefore, we can put a simple "ret" statement at the end of our code. But we must make sure that our pointer to the stack is not damaged, and that our code is not changed.

To communicate a 16-bit application using MASM 6+, we need a 16-bit linker.

ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

Dirk

0
source share

All Articles