![](/img/trans.png)
[英]Why does using "int 21h" on Assembly x86 MASM cause my program to crash?
[英]x86 assembly program does not execute
我是组装的新手,告诉我这是怎么回事,我不知道如何解决此问题。
section .text
global _start
_start:
mov edx,len
mov ecx,msg
mov ebx,1
mov eax,4
mov eax,1
section .data
msg db 'Hello, world!', 0xa ;
len equ $ - msg ;
如前所述,您的程序显然缺少系统调用。
在Windows下(就为Windows生成.EXE文件而言)没有直接的系统调用。 相反,您必须在Windows附带的DLL中调用函数。
例:
mov ecx,len
push ecx
mov ecx,msg
push ecx
mov ecx,1
push ecx
call _write
add esp,12
在32位Windows(或在64位Windows中运行的32位程序)中,基本上有两种类型的函数:stdcall(= WINAPI,CALLBACK,PASCAL)和cdecl。
对于这两种类型的函数,参数必须位于堆栈上(第一个参数必须位于ESP + 0上,第二个参数必须位于ESP + 4上,依此类推),以便您在最后一个先推入时“推”参数示例“ 1”是第一个,“ len”是最后一个)。 函数的结果(如果有的话)将在EAX寄存器中返回(只要它不是浮点值)。
然后调用在DLL中定义的函数。 最后,该函数将进行系统调用,但是该系统调用可能是特定于版本的! 您不必担心。
对于“ stdcall”函数,该函数将从堆栈中删除参数。 (对于参数数量可变的函数(例如wsprintf),仅删除必需的参数。)在汇编器中,此类函数被命名为:
_Name@nnn
而“名称”是C语言中已知的函数名称,而nnn是将从堆栈中删除的字节数。 大多数底层Windows函数是stdcall函数。 请注意,使用字符串的函数通常以“ A”结尾以指示ASCII或以“ W”结尾以指示UNICODE字符串。 通常使用“ A”变体。 示例:调用函数“ MessageBox”:
(push 4 arguments)
call _MessageBoxA@16
大多数C标准库函数都是“ cdecl”-请参见上面的“ write”示例。 Cdecl函数不会调整堆栈指针,因此您必须在“调用”指令之后添加“ add esp,nnn”。 通过在下划线后面添加C函数名称即可简单地形成名称(例如,“ write()”->“ call _write”)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.