可执行文件与64位处理器不兼容 [英] Executable isn't compatible with 64 bits processor
问题描述
我的问题是:当我尝试执行在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
.链接器还将用于解析系统调用,例如WriteConsoleA
,ExitProcess
等.
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.obj
和kernel32.dll
并将它们链接在一起,并生成一个名为main.exe
的可执行文件. kernel32.dll
是包含系统功能WriteConsoleA
,ExitProcess
,ReadConsoleInputA
和GetStdHandle
的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屋!