繁体   English   中英

x86汇编程序不执行

[英]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.

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