문제

방금 Win32에서 일부 X86 어셈블리를 배우기 시작했으며 .AMS 파일 용 IDE와 함께 제공되는 사용자 정의 빌드 규칙을 사용하여 Visual Studio 2008과 MASM을 사용했습니다. DOS 인터럽트를 사용하여 콘솔에 인쇄하려고 노력했지만 대신 "ASMTEST.EXE : 0XC0000005에서 0x00401004의 처리되지 않은 예외 : 액세스 위반 읽기 위치 0xfffffffff." 8 번째 라인에서. 나는 단일 ASCII 문자 'a'(41h)를 출력하려고합니다. 여기에 masm 코드입니다.

.386
.MODEL flat, stdcall

.CODE
start:
    mov dl, 41h
    mov ah, 2
    int 21h
    ret
end start

debug.exe를 사용하고 'a'명령을 사용하여 모든 .code 명령을 입력하고 실행 ( 'g')을 실행하면 잘 작동합니다.

누구든지 DOS 인터럽트를 올바르게 사용하는 방법에 대해 저를 밝힐 수 있습니까? 감사!

편집 : Win32에서 프로그래밍 할 때 Managu는 DOS 인터럽트를 사용하는 대신 WordeConsoLea와 같은 Windows API 호출을 사용해야합니다. 이것 유용한 자원이었습니다. 누구나 (나처럼)이를 수행 할 코드를 찾고있는 경우 여기에 다음과 같습니다.

.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

(진입 점을 메인으로 설정)

도움이 되었습니까?

해결책

Debug.exe를 사용 하여이 코드를 입력하면 16 비트 (8086 아키텍처, "실제 모드") DOS 프로그램을 조립합니다. 당신이 지정한 의미는 그러한 프로그램에 맞습니다. 그러나 MASM으로 여기에있는 프로그램을 조립 한 다음 연결하면 32 비트 (I386 아키텍처, "Protected Mode") Windows 프로그램을 만들려고합니다. 나는 착각 할 수 있지만, 후자의 경우에 INT 21H를 합법적으로 불러 일으킬 수는 없다고 생각합니다.

다른 팁

'ret'명령으로 인해 발생할 수 있습니다. 어디로 돌아가고 있습니까? 메모리에 알려지지 않은 곳은 상상합니다.

대신 int 20h를 사용해보십시오. 그것은 "우아하게"나갈 것입니다.

더 "관리되는"환경이기 때문에 디버그 (아마도)에서 작동합니다.

16 비트 DOS-*. com 응용 프로그램을 시작하면 DOS가 Offset 0에서 PSP 내부의 "int 20"명령의 OPCODE를 채우고 추가 DOS는 DOS가 응용 프로그램을 실행하기 전에 스택에 0을 누릅니다. 따라서 코드 끝에 간단한 "RET"명령을 배치 할 수 있습니다. 그러나 우리는 스택 포인터가 손상되지 않았고 코드그먼트가 변경되지 않도록해야합니다.

MASM 6+를 사용하여 16 비트 응용 프로그램을 연결하려면 16 비트 링커가 필요합니다.

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

단도

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top