assembly Visual Studio 2019 - 32位程序集-世界,您好

mwkjh3gx  于 2023-01-30  发布在  其他
关注(0)|答案(2)|浏览(177)

我通过“MIPS汇编”学习了汇编语言编程的概念。我写了几个程序,如斐波纳契,堆栈相关的东西等。现在我想进入下一个层次,32位Windows汇编的.386指令集。
这是我已经拥有的。

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, deExitCode:DWORD

.data
msg db "Hello, World!", 0

.code

main PROC

    INVOKE ExitProcess, 0
main ENDP
END main

但是我怎么调用像print_string这样的系统函数呢?我真的不知所措。我尝试了一些相关的SO答案,但是它们使用NASM,所以对我来说不起作用。

hmae6n7t

hmae6n7t1#

这是一个基本的WIN32控制台模式 HelloWorld! ASM程序,用MASM 615编译,运行在我的Win10,64位系统上。如果有任何修改(如果有),可以咨询作者的网站,使其编译VS 2019等。

; 32-Bit Intel Protected Mode Programming
; KIP IRVINE Assembly Language for x86 / Intel-Based Computers. 
;

.386
.model flat,stdcall
.stack 4096

; DEFINE/DECLARE necessary WIN32 constants, functions etc.
;------------------------------------------------------------
; Win32 Console handles
STD_OUTPUT_HANDLE EQU -11       ; predefined Win API constant

; ALIAS  : The following Win32 API functions have an
; extra "A" at the end of their name, 
; so they are redefined here with text macros:
WriteConsole EQU <WriteConsoleA>

;                   FUNCTION PROTOTYPES
; -------------------------------------------------------------
ExitProcess PROTO,          ; exit program
    dwExitCode:DWORD        ; return code

GetStdHandle PROTO,         ; get standard handle
    nStdHandle:DWORD        ; type of console handle

WriteConsole PROTO,                 ; write a buffer to the console
    handle:DWORD,                   ; output handle
    lpBuffer:PTR BYTE,              ; pointer to buffer
    nNumberOfBytesToWrite:DWORD,    ; size of buffer
    lpNumberOfBytesWritten:PTR DWORD,   ; num bytes written
    lpReserved:DWORD                    ; (not used)

; User Defined Data Section
; ---------------------------------------------------------------
.data
mesg1               BYTE    "Hello world!",0dh,0ah,0
sizeMesg1           = ($-mesg1)-1       ; ex-cluding the sign bit
BytesWritten        DWORD   0
ConsoleOutHandle    DWORD   0

.code
main proc
    
    ; Get Standart Output Handle
    INVOKE GetStdHandle, STD_OUTPUT_HANDLE  ; Get a handle to console SCREEN.
    mov ConsoleOutHandle, eax
    
    ; Write Message to the Handle => CONSOLE
    INVOKE WriteConsole, ConsoleOutHandle, ADDR mesg1, (LENGTHOF mesg1)-1, ADDR BytesWritten, 0
    
    
    invoke ExitProcess,0
main endp
;-------------------------------------------------------------------

end main
uqjltbpv

uqjltbpv2#

启用指令并使用指向字符串的指针调用printf的示例masm代码。之所以指定旧库,是因为从Visual Studio 2015开始,printf和scanf现在在编译C源文件时内联,而汇编将需要使用旧库。如果程序同时包含C和汇编源文件,则不需要旧库。
可能需要自定义生成步骤。创建一个空的Windows控制台项目,添加程序集源文件,右键单击程序集源文件名,然后单击属性,将"从生成中排除"设置为"否",然后设置自定义生成步骤参数:
对于调试版本:

command line: ml /c /Zi /Fo$(OutDir)\example.obj example.asm
output file:  $(OutDir)\example.obj

对于发布版本,不需要Zi:

command line: ml /c /Fo$(OutDir)\example.obj example.asm
output file:  $(OutDir)\example.obj

示例源代码:

.686p                   ;enable instructions
        .xmm                    ;enable instructions
        .model flat,c           ;use C naming convention (stdcall is default)

;       include C libraries
        includelib      msvcrtd
        includelib      oldnames
        includelib      legacy_stdio_definitions.lib    ;for scanf, printf, ...

        .data                   ;initialized data
pfstr   db      "Hello world!",0dh,0ah,0
        .data?                  ;uinitialized data
        .stack  4096            ;stack (optional, linker will default)

        .code                   ;code 
        extrn   printf:near
        public  main

main    proc

        push    offset pfstr
        call    printf
        add     sp,4 

        xor     eax,eax
        ret
main    endp

        end

对于64位版本,请使用ml64.exe而不是ml.exe。

相关问题