; Test3_1.asm; 测试代码前应先建立一个控制台工程: 文件 -> 新建工程 -> Console App ....386.model flat, stdcallinclude masm32.incinclude kernel32.incincludelib masm32.libincludelib kernel32.lib.data szText db "Hello World!", 0.codestart: invoke StdOut, addr szText ret ;ret 是用于子程序返回的指令, 这里用它代替 ExitProcess(在没有生成 Win32 窗口时是可以的)end start使用系统 API 函数:
; Test3_2.asm.386.model flat, stdcallinclude windows.incinclude kernel32.incincludelib kernel32.lib.data szText db 'Hello World!', 0;定义两个 DWORD 类型的变量, 分别是用于输出句柄和字符串长度.data? hOut dd ? len dd ?.codestart: ; 获取控制台输出设备的句柄, 其返回值会放在 eax 寄存器 invoke GetStdHandle, STD_OUTPUT_HANDLE ; 把获取到的句柄给变量 hOut mov hOut, eax ; 通过 lstrlen 函数获取字符串长度, 返回值在 eax invoke lstrlen, addr szText ; 把获取到的字符串长度给变量 len mov len, eax ; 输出到控制台, 参数分别是: 句柄、字符串地址、字符串长度; 后面是两个指针暂用不到 invoke WriteFile, hOut, addr szText, len, NULL, NULL retend start; 另外前面用到的 StdOut 也基本就是这样实现的, 源码在: masm32\m32lib\stdout.asm使用微软 C 标准库中的 printf 函数; msvscrt.inc 把它声明做 crt_printf
; Test3_3.asm.386.model flat, stdcallinclude msvcrt.incincludelib msvcrt.lib.data szText db 'Hello World!', 0.codestart: invoke crt_printf, addr szText retend start三种方法相比之下, 应推荐使用 C 函数 crt_printf; 因为它可以方便输出更多数据类型, 如:
; Test3_4.asm.386.model flat, stdcallinclude msvcrt.incincludelib msvcrt.lib.data szFmt db 'EAX=%d; ECX=%d; EDX=%d', 0.codestart: mov eax, 11 mov ecx, 22 mov edx, 33 invoke crt_printf, addr szFmt, eax, ecx, edx retend start