可执行文件与64位处理器不兼容 [英] Executable isn't compatible with 64 bits processor

查看:122
本文介绍了可执行文件与64位处理器不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:当我尝试执行在NASM和Windows 8中汇编的.exe时,64位告诉我该.exe与64位不兼容.那么,我应该如何汇编这些代码(我是从Web上获得的)?

My problem is that this: When I try to execute an .exe assembled in NASM and Windows 8 64 bits tells me that this .exe isn't compatible with 64 bits. So, how should I assemble this code (I obtained it from the Web)?

使用的代码

STD_OUTPUT_HANDLE   equ -11
STD_INPUT_HANDLE    equ -10
NULL                equ 0

global start
extern ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

section .data    ;message we want to display on console
    msg                 db "Press a key to continue...", 13, 10, 0
    msg.len             equ $ - msg
    consoleInHandle     dd 1

section .bss     ;buffers declaration
    buffer_out          resd 2
    buffer_in           resb 32

section .text
    start:       ;starting point of our program
        push    STD_OUTPUT_HANDLE
        call    GetStdHandle   ;call to get a handle to the
        push    NULL           ;specified mode (input, output...)
        push    buffer_out
        push    msg.len
        push    msg
        push    eax            ;contains the GetStdHandle result
        call    WriteConsoleA  ;call to print our msg in console

    read:
        push    STD_INPUT_HANDLE
        call    GetStdHandle        ;new call to get input handle
        push    NULL
        push    1
        push    buffer_in
        push    eax
        call    ReadConsoleInputA   ;call to detect user input
                                    ;this function will wait til
    exit:                           ;it detects enough keypresses
        push    NULL                ;(in this case, 1)
        call    ExitProcess

用于汇编此命令: nasm -fwin32 main.asm -o main.exe

Command used to assemble this: nasm -fwin32 main.asm -o main.exe

推荐答案

您以这种方式运行汇编程序:

You ran the assembler this way:

nasm -fwin32 main.asm -o main.exe

如果使用-fwin32进行汇编,则不会生成可执行文件.它实际上会生成一个目标文件.问题是在这种情况下,OBJ文件不是可执行文件.就像获取一个TXT文件,将其重命名为EXE并尝试运行该文件一样.不会的

If you assemble with -fwin32 this will not generate an executable. It actually generates an object file. The issue is that an OBJ file in this case is not an executable. It would be like taking a TXT file, renaming it an EXE and trying to run that. It won't.

因此,您应该以这种方式执行nasm:

So you should have executed nasm this way:

nasm -fwin32 main.asm -o main.obj

这将输出文件main.obj.您无法运行目标文件.链接程序必须对其进行处理以产生exe.链接器还将用于解析系统调用,例如WriteConsoleAExitProcess等.

This outputs a file main.obj. You can't run an object file. It must be processed by a linker to produce an exe. The linker will also be used to resolve the systems calls like WriteConsoleA, ExitProcess etc.

有很多链接器,其中包括Microsoft的名为 link.exe 的链接器.我不知道您是否安装了Microsoft编译器,因此我建议您使用免费的编译器来帮助您.您可以从此处下载一个名为GoLink的文件.您可以在此处阅读GoLink手册.下载完成后,您可以将 GoLink.exe 提取到与 nasm.exe 相同的目录.

There are many linkers out there including Microsoft's linker called link.exe. I do not know if you have a Microsoft compiler installed or not, so I am going to recommend using a free one to help you along. You can download one called GoLink from here. You can read the GoLink manual here. Once downloaded you can extract GoLink.exe to the same directory as your nasm.exe.

用于链接main.obj生成main.exe所需的命令是:

The command you will need to use to link main.obj to produce main.exe is:

GoLink.exe main.obj kernel32.dll /fo main.exe /console

这将使用main.objkernel32.dll并将它们链接在一起,并生成一个名为main.exe的可执行文件. kernel32.dll是包含系统功能WriteConsoleAExitProcessReadConsoleInputAGetStdHandle的DLL(共享库).如果没有它,链接器将无法创建最终的可执行文件,并且将退出并显示错误信息.

This will take main.obj and kernel32.dll and link them together and produce an executable called main.exe. kernel32.dll is the DLL(shared library) that holds the system functions WriteConsoleA, ExitProcess, ReadConsoleInputA and GetStdHandle. Without it the linker will not be able to create a final executable and will exit with an error saying as such.

您的程序中有一个主要问题,当输入字符时,它很可能会崩溃.我已对其进行了修改,使其看起来像这样:

You have one major problem in your program that will likely make it crash when inputting characters. I have modified it to look like this:

STD_OUTPUT_HANDLE   equ -11
STD_INPUT_HANDLE    equ -10
NULL                equ 0

global start
extern ExitProcess, GetStdHandle, WriteConsoleA, ReadConsoleInputA

section .data    ;message we want to display on console
    msg                 db "Press a key to continue...", 13, 10, 0
    msg.len             equ $ - msg

section .bss     ;buffers declaration
    buffer_out          resd 1
    buffer_in           resb 32
    events_read         resd 1

section .text
    start:       ;starting point of our program
        push    STD_OUTPUT_HANDLE
        call    GetStdHandle   ;call to get a handle to the
        push    NULL           ;specified mode (input, output...)
        push    buffer_out
        push    msg.len
        push    msg
        push    eax            ;contains the GetStdHandle result
        call    WriteConsoleA  ;call to print our msg in console

    read:
        push    STD_INPUT_HANDLE
        call    GetStdHandle        ;new call to get input handle
        push    events_read         ;push dword buffer to return # of events read
                                    ;This paramater can't be NULL/0
        push    1
        push    buffer_in
        push    eax
        call    ReadConsoleInputA   ;call to detect user input
                                    ;this function will wait til
    exit:                           ;it detects enough keypresses
        push    NULL                ;(in this case, 1)
        call    ExitProcess

您的代码最初具有:

push    NULL

我将其更改为:

push    events_read         ;push dword buffer to return # of events read
                            ;This paramater can't be NULL/0

我还添加了events_read变量(在.bss部分中分配了resd的单个 DWORD ):

I also added the events_read variable (a single DWORD allocated with resd to the .bss section):

    events_read         resd 1

您可以找到ReadConsoleInputA 此处以了解有关参数的更多信息.请注意,使用32位Windows应用程序参数时,其顺序与文档中显示的顺序相反.该文档说:

You can find the Microsoft documentation for ReadConsoleInputA here to find out more about the parameters. Note that with 32 bit windows applications parameters are pushed onto the stack in reverse order as they appear in the documentation. The documentation says:

布尔WINAPI ReadConsoleInput( _输入_ hConsoleInput, _Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead );
BOOL WINAPI ReadConsoleInput( _In_ HANDLE hConsoleInput, _Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead );

参数

hConsoleInput [输入]控制台输入缓冲区的句柄.手柄 必须具有GENERIC_READ访问权限.有关更多信息,请参见 控制台缓冲区安全性和访问权限.

hConsoleInput [in] A handle to the console input buffer. The handle must have the GENERIC_READ access right. For more information, see Console Buffer Security and Access Rights.

lpBuffer [out]指向的指针 接收输入缓冲区的INPUT_RECORD结构的数组 数据.该缓冲区的存储是从共享堆分配的,用于 该过程的大小为64 KB.缓冲区的最大大小将 取决于堆的使用情况.

lpBuffer [out] A pointer to an array of INPUT_RECORD structures that receives the input buffer data. The storage for this buffer is allocated from a shared heap for the process that is 64 KB in size. The maximum size of the buffer will depend on heap usage.

nLength [in]指向的数组的大小 lpBuffer参数,以数组元素为单位.

nLength [in] The size of the array pointed to by the lpBuffer parameter, in array elements.

lpNumberOfEventsRead [输出] 指向接收输入记录数的变量的指针 阅读.

lpNumberOfEventsRead [out] A pointer to a variable that receives the number of input records read.

这篇关于可执行文件与64位处理器不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆