3

结果到我的帖子我可以在 windows xp 上使用 int21h 来打印东西吗?,我看过一篇关于使用 Windows API 的文章,在这篇文章中提到了使用 _WriteConsole@4 API 将消息打印到控制台。该文章位于http://cs.lmu.edu/~ray/notes/x86assembly/

到目前为止,这是我的代码:

.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

我正在使用这种语法来编译代码:ML:

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

关联:

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

我已经让它编译和链接,但是当我运行生成的 .exe 时,它​​什么也不做,甚至没有返回错误。控制台只是黑色的。为什么是这样?

任何帮助将不胜感激。对于这个论坛的用户,我为每天轰炸 stackoverflow.com 道歉,只是我学习的资源很少。

提前致谢,

程序

4

3 回答 3

3

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

在 masm32rt.inc 之前添加 masm32\include 目录的绝对路径。当您使用它时,在文本编辑器中打开 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 已经包含它,它包含用于库的 include 和 includelib 以及广泛使用的包含。我们用它来节省一堆打字。

现在打开 \masm32\include 中的任何包含文件,包含只是为 API 调用设置原型,因此您可以使用 invoke 进行参数检查,它还为 API 调用设置别名,因此我们不必键入 WriteConsoleA 而是我们只需编写WriteConsole 地狱,你甚至可以做 YoConsole equ 并且在你的代码中你会为 WriteConsole 编写 YoConsole。

话虽这么说,我们不使用 - extern _WriteConsoleA@20:near,因为 NASM 也不需要将我们的入口标签设置为公共 MASM 通过以下方式知道您的入口点:

.code
yourentrypointname:

end yourentrypointname

我们也不必为链接器指定库,因为我们在源代码中使用了 includelib。

另外,不要,我再说一遍,不要养成在参数中使用硬编码数字的习惯。现在就改掉这个习惯!!Windows 头文件使用 DEFINES 是有原因的 - 代码可读性,我们(帮助您的人)不需要查找 -11 对该 API 调用的含义,我使用了定义,您知道该参数的含义。另外,如果您有 40 次 WriteConsole 调用怎么办?如果您使用等式,则只需更改等式而不是搜索和替换。如果您想要体面的 MASM 教程,请搜索 Iczelion,它们很旧并且包含一些错误,但它们会让您入门,我们中的许多人在早期都使用过这些教程。

于 2012-05-18T21:42:41.660 回答
3

这没有问题:

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 所以它创建控制台但不执行任何代码!在这种情况下你不需要告诉链接器入口点,你的入口点是 start... 链接器是怎么知道的?结束的开始

于 2012-05-18T03:14:04.893 回答
1

您可以尝试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

但是,如果您想坚持使用当前的汇编程序,我们可以在 macros.asm 下查看有一个 print Macro :

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

所以你想要 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

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

于 2012-05-17T13:20:37.537 回答