Winapi x86程序集-如何使用Windows API_WriteConsole@4-masm32语法

Winapi x86程序集-如何使用Windows API_WriteConsole@4-masm32语法,winapi,assembly,x86,masm,masm32,Winapi,Assembly,X86,Masm,Masm32,在我的帖子中,我可以在windows xp上使用int21h打印东西吗?,我看过一篇关于使用windows API的文章,在这篇文章中,我参考了使用_WriteConsole@4API将消息打印到控制台。这篇文章在 以下是我目前的代码: .386P .model flat extern _ExitProcess@4:near extern _GetStdHandle@4:near extern _WriteConsoleA@20:near public _go .data

在我的帖子中,我可以在windows xp上使用int21h打印东西吗?,我看过一篇关于使用windows API的文章,在这篇文章中,我参考了使用_WriteConsole@4API将消息打印到控制台。这篇文章在

以下是我目前的代码:

.386P
.model  flat
extern  _ExitProcess@4:near
extern  _GetStdHandle@4:near
extern  _WriteConsoleA@20:near
public  _go

.data
      msg     byte    'if you get this, it worked.', 10
      handle  dword   ?
      written dword   ?
.code 
start:
_go:    
      push    -11
      call    _GetStdHandle@4
      mov     handle, eax
      push    0
      push    offset written
      push    13
      push    offset msg
      push    handle
      call    _WriteConsoleA@20
      push    0
      call    _ExitProcess@4
end start
我使用以下语法编译代码: 毫升:

链接:

我已经让它编译和链接,但当我运行生成的.exe时,它完全不做任何事情,甚至没有返回错误。控制台是黑色的。为什么会这样

任何帮助都将不胜感激。对于这个论坛的用户,我为每天轰炸stackoverflow.com表示歉意,因为我只有很少的资源可以学习

提前感谢,

Progrmr

您可以尝试,下面是一个hello world控制台应用程序示例:

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« *

    .486
    .model flat, stdcall
    option casemap :none   ; case sensitive

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\kernel32.inc
    include \masm32\macros\macros.asm

    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\kernel32.lib

    .code

start:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    print "Hello world"

    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
但是如果您想继续使用当前的汇编程序,我们可以查看macros.asm下的print宏:

print MACRO arg1:REQ,varname:VARARG      ;; display zero terminated string
    invoke StdOut,reparg(arg1)
  IFNB <varname>
    invoke StdOut,chr$(varname)
  ENDIF
ENDM

因此,在这段旅程结束时,您必须使用WriteFile而不是WriteConsole:)

这可以毫无问题地工作:

include masm32rt.inc

.data
szMsg       db  "I am in the console!", 0
MSG_LEN     equ $ - szMsg

.data?
BytesWriten dd  ?

.code
start:
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle

    push    NULL
    push    offset BytesWriten
    push    MSG_LEN
    push    offset szMsg
    push    eax
    call    WriteConsole

    push    0
    call    ExitProcess
end start

您的条目标签是_go,但您告诉链接器是go-/entry:go,因此它创建了控制台,但不执行任何代码!你不需要告诉链接器入口点在这种情况下,你的入口点是开始。。。链接器如何知道?结束-开始

首先,您获得示例代码的链接来自一位NASM用户,他可能从未使用过他所说的MASM。他还像NASM格式一样编写MASM示例。事实上,你想使用汇编意味着你必须是一个高级计算机用户。您需要知道如何使用批处理文件、如何设置系统路径以及其他事项。当出现问题时,你通过研究来学习。所以你有一个错误,说它找不到masm32rt.inc,但你说你正在使用MASM32。我使用批处理文件和IDE进行汇编,我的系统路径指向MASM32中的各个目录

将绝对路径添加到masm32\include目录中的masm32rt.inc之前。当您使用时,在文本编辑器中打开masm32rt.inc,查看其中的内容-已修复错误

You start your source file with:
.586
.option casemap:NONE
.model flat, stdcall

include yourincludeshere and it could be a bunch
includelib yourlibshere same here a bunch
masm32rt.inc已经包含了该功能,并且包含了广泛使用的libs和include的include和includelib。我们用它来节省大量的打字

现在打开\masm32\include中的任何include文件。include只是为API调用设置protos,因此您可以使用invoke进行参数检查,它还为API调用添加别名,因此我们不必键入WriteConsoleA,而只需编写WriteConsole hell,您甚至可以执行YoConsole eq,并在代码中为WriteConsole编写YoConsole

也就是说,我们不使用-extern_WriteConsoleA@20:接近NASM,我们也不需要将我们的入口标签设置为public MASM通过以下方式了解您的入口点:

.code
yourentrypointname:

end yourentrypointname
我们也不必为链接器指定lib,因为我们在源代码中使用includelib

另外,我重复一遍,不要养成在参数中使用硬编码数字的习惯。现在就改掉那个习惯!!Windows头文件使用define的原因是代码可读性,我们(帮助您的人)不需要查找-11对于API调用的含义,我使用define,您知道该参数的含义。再加上如果你打了40次WriteConsole电话怎么办?如果使用equale,则只需更改equale,而不是搜索和替换。
如果你想要一个像样的MASM教程来搜索Iczelion,它们很旧并且包含一些错误,但是它们会让你开始学习,我们很多人在早期都使用过这些教程

在Visual Studio 2010(10.00.40219.01)上对我有效,不过您应该将
13
调整为
msg
的实际长度。真的吗?我正在使用命令提示符并在帖子中键入
ml
链接
字符串。我怎样才能让它工作呢?WriteFile和WriteConsole之间的语法有什么不同吗?或者我可以用同样的语法将WriteFile换成WriteConsole吗?我只是尝试在程序中使用
WriteFile
,但它没有编译。它给了我一个错误,即:
未定义的外部
。你能给我一些代码来告诉我该怎么做吗?那你为什么不使用打印宏呢?这是使用windows API还是masm库宏?你是用什么编译的?我试着用以下代码编译它:
ml test.asm/c
link test.obj c:\masm32\include\masm32rt.inc/subsystem:console
它不起作用。它说,
无法打开文件:masm32rt.inc
。我最终让它通过了
ml
部分,但当谈到链接时,它说,
无效或损坏的文件
。这是为什么?你用什么制作和链接这个文件?我一直在使用批处理文件来创建此文件,只是没有将%path%环境变量设置为任何MASM目录。我完全使用了您的代码,它仍然显示
无法打开文件:masm32rt.inc
。在批处理文件中,我切换到目录
C:\masm32\bin
,然后执行
ml/C/coff test.asm
。然后我执行
cd C:\masm32\bin
链接/子系统:控制台C:\masm32\inc\masm32rt.inc test.obj
。这是正确的吗?如果没有,你能发布一个一步一步的方法来做到这一点吗。谢谢你抽出时间。
include masm32rt.inc

.data
szMsg       db  "I am in the console!", 0
MSG_LEN     equ $ - szMsg

.data?
BytesWriten dd  ?

.code
start:
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle

    push    NULL
    push    offset BytesWriten
    push    MSG_LEN
    push    offset szMsg
    push    eax
    call    WriteConsole

    push    0
    call    ExitProcess
end start
You start your source file with:
.586
.option casemap:NONE
.model flat, stdcall

include yourincludeshere and it could be a bunch
includelib yourlibshere same here a bunch
.code
yourentrypointname:

end yourentrypointname