无法通过NASM获得用户输入

时间:2018-04-16 16:44:55

标签: linux nasm windows-subsystem-for-linux sasm

我正在教自己NASM,我在获取用户输入方面遇到了一些麻烦。 (我已经知道MIPS了,我对x86很熟悉)。起初我正在尝试使用示例代码here的在线编译器,但是虽然它打印到屏幕上但它实际上从未暂停请求输入。我尝试在运行它之前将一个数字放入stdin窗口,但这也不起作用。

我接下来尝试的是直接从linux运行它,所以我安装了NASM(我使用的是Ubuntu,适用于Linux的Windows子系统),但是在编译并获得可执行文件后,它只是在第一次系统调用时退出而没有打印或要求输入。我尝试在我的VM上运行(Ubuntu 14.04)并且确实有效(是的!)但是我的VM非常慢,所以我尽量避免使用它。知道为什么它会在那里工作但不在我的子系统上工作吗?

我决定尝试切换到IDE(我习惯使用Mars for MIPS)并安装SASM,它似乎正在工作,除了它们有一个单独的用户输入窗口,而不是在程序运行时要求输入。我发现的大多数在线编译器都有这个,我对它为什么会有点困惑。我想编写一个简单的hangman程序来熟悉NASM,但在运行程序之前输入输入并不能真正起作用。

任何帮助都会受到赞赏,我不知道为什么VM工作但WSL没有,我真的不想使用我的VM,因为我的笔记本电脑已经很老了,而且速度太慢了。

谢谢!

我最初运行的代码是:

section .data                           ;Data segment
   userMsg db 'Please enter a number: ' ;Ask the user to enter a number
   lenUserMsg equ $-userMsg             ;The length of the message
   dispMsg db 'You have entered: '
   lenDispMsg equ $-dispMsg                 

section .bss           ;Uninitialized data
   num resb 5

section .text          ;Code Segment
   global _start

_start:                ;User prompt
   mov eax, 4
   mov ebx, 1
   mov ecx, userMsg
   mov edx, lenUserMsg
   int 80h

   ;Read and store the user input
   mov eax, 3
   mov ebx, 2
   mov ecx, num  
   mov edx, 5          ;5 bytes (numeric, 1 for sign) of that information
   int 80h

   ;Output the message 'The entered number is: '
   mov eax, 4
   mov ebx, 1
   mov ecx, dispMsg
   mov edx, lenDispMsg
   int 80h  

   ;Output the number entered
   mov eax, 4
   mov ebx, 1
   mov ecx, num
   mov edx, 5
   int 80h  

   ; Exit code
   mov eax, 1
   mov ebx, 0
   int 80h

编译:

nasm -f elf64 test.asm
ld test.o -o test

然后跑步:

./test

子系统上的uname -m的Ouptut :(在VM上相同)

x86_64

子系统上的文件测试输出:(在VM上相同)

test: ELF 64-bit LSB executeable, x86-64, version 1 (SYSV), statically linked, not stripped
编辑:所以我明白了! WSL根本不支持32位,您必须使用64 bit syscall interface。我保持这个问题,因为有人可能会觉得它很有用,而且我也很困惑为什么输入从未在在线编译器上工作,以及为什么大多数在线编译器和NASs的IDE都有一个单独的stdin输入窗口。

1 个答案:

答案 0 :(得分:0)

正如你在对自己的评论中所说,你的问题是在wsl中缺少32位系统调用(int 80)支持。

使用binfmt和qemu-static,您可以从其他Linux目标运行二进制文件。 qemu-static做的是模拟usermode中的指令集(i386在x86上不需要太多仿真),但是将系统调用转换为内核本身使用的调用。

  

尝试在我的虚拟机(Ubuntu 14.04)上运行,这确实有效(是的!)但我的   VM非常慢,所以我尽量避免使用它....任何帮助都可以   我将不胜感激,我不知道为什么VM工作但WSL没有   而且我真的不想使用我的虚拟机,因为我的笔记本电脑已经过时了   超慢。

这在你的情况下应该很有用,至少对于64位x86上的32位x86它非常快,因为它是一个非常薄的层。

对于wsl,当有人想要run arm binaries时,它首先被探索过,但是作为副作用,它被注意到它也适用于32位x86模式。

Here are the instructions on its requirements and how to get it working。它非常简单易行。

可以在QemuUserEmulation的qemu文档中找到一些其他信息。

有了这个,您不仅可以尝试32位和32位的手。 nasm,但你可以采用其他指令集的方法,比如你已经知道的mips,或者学习一些arm,sparc,ppc。