简体   繁体   English

x86程序集 - 如何使用Windows API _WriteConsole @ 4 - masm32语法

[英]x86 assembly - how to use Windows API _WriteConsole@4 - masm32 syntax

In result to my post Can I use int21h on windows xp to print things? 结果我的帖子我可以在windows xp上使用int21h来打印东西吗? , I have seen an article about using Windows API's and in this article was a reference to using the _WriteConsole@4 API to print a message to the console. ,我看过一篇关于使用Windows API的文章,在本文中引用了使用_WriteConsole @ 4 API将消息打印到控制台。 The article is at http://cs.lmu.edu/~ray/notes/x86assembly/ . 该文章位于http://cs.lmu.edu/~ray/notes/x86assembly/

Here is my code so far: 到目前为止,这是我的代码:

.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

I am using this syntax to compile the code: ML: 我使用这种语法来编译代码:ML:

ml (the file is called test.asm) test.asm /c

Link: 链接:

link test.obj C:\masm32\lib\kernel32.lib /SUBSYSTEM:CONSOLE /entry:go

I have gotten it to compile and link, but when I run the .exe that is produced, it does absolutely nothing, not even an error return. 我已经得到它来编译和链接,但是当我运行生成的.exe时,它什么都没做,甚至没有错误返回。 The console is just black. 控制台只是黑色。 Why is this? 为什么是这样?

Any help would be greatly appreciated. 任何帮助将不胜感激。 And to the users of this forum, I apologize for bombarding stackoverflow.com every day, it is just that I have very few resources to learn with. 对于这个论坛的用户,我为每天轰炸stackoverflow.com道歉,这只是我很少有资源可以学习。

Thanks in advance, 提前致谢,

Progrmr Progrmr

This works without problem: 这没有问题:

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

your entry label is _go yet you tell the linker is is go - /entry:go so it creates the console but does not execute any code! 您的条目标签是_go但是您告诉链接器是go - / entry:go所以它创建控制台但不执行任何代码! You don't need to tell the linker the entry point in this case, your entry point is start... How does the linker know? 在这种情况下,您不需要告诉链接器入口点,您的入口点就是开始...链接器如何知道? The end start 结束了

First off, the link you are getting your sample code is from a NASM user and he probably never used MASM from the way he speaks of it. 首先,您获取示例代码的链接来自NASM用户,他可能从未使用MASM,就像他说的那样。 He also writes his MASM sample like NASM format. 他还像NASM格式一样写了他的MASM样本。 The fact that you want to use Assembly means you have to be an advanced computer user. 您想要使用Assembly的事实意味着您必须是高级计算机用户。 You need to know how to use batch files, how to set system paths and other things. 您需要知道如何使用批处理文件,如何设置系统路径和其他事项。 When something goes wrong, you learn by researching. 当出现问题时,你会通过研究来学习。 So you got an error saying it can't find masm32rt.inc but you say you are using MASM32. 所以你得到一个错误,说它找不到masm32rt.inc,但你说你正在使用MASM32。 I use batch files and an IDE for Assembly and I have my system paths pointing to various directories in MASM32. 我使用批处理文件和IDE进行汇编,我的系统路径指向MASM32中的各种目录。

Add the absolute path to your masm32\\include directory before masm32rt.inc. 在masm32rt.inc之前添加masm32 \\ include目录的绝对路径。 While you are at it, open masm32rt.inc in a text editor and see what is in it - error fixed. 当你在它时,在文本编辑器中打开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 contains that already and it contains include and includelib for libs and includes that are widely used. masm32rt.inc已经包含了它,它包含libs的include和includelib以及广泛使用的包含。 We use it to save a bunch of typing. 我们用它来节省一堆打字。

Now open any include file in \\masm32\\include the includes are just setting up the protos for the API calls so you can use invoke for parameter checking, it also aliases the API calls so we don't have to type WriteConsoleA instead we just write WriteConsole hell, you could even do YoConsole equ and in your code you would write YoConsole for WriteConsole. 现在打开\\ masm32 \\ include中的任何包含文件include只是为API调用设置原型,因此你可以使用invoke进行参数检查,它也可以对API调用进行别名,所以我们不必输入WriteConsoleA而只是写WriteConsole地狱,你甚至可以做YoConsole equ,你可以在你的代码中为WriteConsole写YoConsole。

That being said, we don't use - extern _WriteConsoleA@20:near as NASM would nor do we need to set our entry label to public MASM knows your entry point by this: 话虽这么说,我们不使用 - extern _WriteConsoleA @ 20:附近因为NASM也不需要将我们的条目标签设置为公共MASM知道你的入口点:

.code
yourentrypointname:

end yourentrypointname

we also don't have to specify the libs to the linker since we use includelib in our source. 我们也不必为链接器指定库,因为我们在源代码中使用了includelib。

Also, DO NOT, I repeat DO NOT get into the habit of using hard coded numbers in your parameters. 另外,不要,我再说一遍,不要养成在参数中使用硬编码数字的习惯。 Get out of that habit NOW!! 现在摆脱那种习惯!! Windows header files use DEFINES for a reason - code readability, We (the folks that help you) don't need to lookup what -11 means for that API call, I used the define and you know what that parameter means. Windows头文件使用DEFINES是有原因的 - 代码可读性,我们(帮助你的人)不需要查找-11对于该API调用的含义,我使用了define并且您知道该参数的含义。 Plus what if you have that WriteConsole call 40 times? 如果你有4次WriteConsole调用怎么办? If you use an equate, you need to change just the equate instead of search and replace. 如果使用equate,则需要仅更改equate而不是search and replace。 If you want decent MASM tutorials search for Iczelion they are old and contain a few errors but they will get you started, many of us in the early days have used those tutorials. 如果你想要体面的MASM教程搜索Iczelion它们已经很老了并且包含一些错误但是它们会让你开始,我们很多人在早期都使用过那些教程。

You could try MASM32 , here is a hello world example for console application : 您可以尝试使用MASM32 ,这是控制台应用程序的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

But if you want to stick with your current assembler, we can look under macros.asm there is a print Macro : 但是如果你想坚持使用当前的汇编程序,我们可以在macros.asm下看一下打印宏:

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

So you want StdOut, in MASM32 it looks like this : 所以你想要StdOut,在MASM32中它看起来像这样:

StdOut proc lpszText:DWORD

    LOCAL hOutPut  :DWORD
    LOCAL bWritten :DWORD
    LOCAL sl       :DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut, eax

    invoke StrLen,lpszText
    mov sl, eax

    invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL

    mov eax, bWritten
    ret

StdOut endp

So at the end of this journey, you have to use WriteFile not WriteConsole :) 所以在这个旅程结束时,你必须使用WriteFile而不是WriteConsole :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM