当前位置: 首页 > 面试题库 >

Windows上的Ubuntu上的Bash上的汇编编译可执行文件不产生输出

通鸿风
2023-03-14
问题内容

我一直在寻找有关汇编的教程,并且正在尝试运行一个hello world程序。我在Windows的Ubuntu上使用Bash。

这是程序集:

section .text
    global _start     ;must be declared for linker (ld)

_start:             ;tells linker entry point
    mov edx,len     ;message length
    mov ecx,msg     ;message to write
    mov ebx,1       ;file descriptor (stdout)
    mov eax,4       ;system call number (sys_write)
    int 0x80        ;call kernel

    mov eax,1       ;system call number (sys_exit)
    int 0x80        ;call kernel

section .data
    msg db 'Hello, world!', 0xa  ;string to be printed
    len equ $ - msg     ;length of the string

我正在使用以下命令来创建可执行文件:

nasm -f elf64 hello.asm -o hello.o
ld -o hello hello.o -m elf_x86_64

我使用以下命令运行它:

./hello

然后,该程序似乎在运行时没有出现段错误或错误,但没有任何输出。

我不知道为什么代码不会产生输出,但是我想知道在Windows上的Ubuntu上使用Bash是否与此有关?为什么它不产生输出,我该如何解决?


问题答案:

问题出在Windows的Ubuntu(Linux的Windows子系统)上。它仅支持64位syscall接口, int 0x80支持32位x86系统调用机制。

除了无法int 0x80在64位二进制文​​件中使用(32位兼容性)之外,Windows上的Ubuntu(WSL)也不支持运行32位可执行文件。

您需要从使用转换int 0x80syscall。不难
a使用一组不同的寄存器,syscall并且系统调用号与其32位对应号不同。Ryan
Chapman的博客中
包含有关syscall界面,系统调用及其参数的信息。Sys_writeSys_exit以这种方式定义:

%rax  System call  %rdi               %rsi              %rdx

%r10 %r8 %r9

0     sys_read     unsigned int fd    char *buf         size_t count  
1     sys_write    unsigned int fd    const char *buf   size_t count
60    sys_exit     int error_code

使用syscall也则会覆盖 RCXR11 寄存器。它们被认为是易变的。结束后不要依赖于它们具有相同的值syscall

您的代码可以修改为:

section .text
    global _start     ;must be declared for linker (ld)

_start:             ;tells linker entry point
    mov edx,len     ;message length
    mov rsi,msg     ;message to write
    mov edi,1       ;file descriptor (stdout)
    mov eax,edi     ;system call number (sys_write)
    syscall         ;call kernel

    xor edi, edi    ;Return value = 0
    mov eax,60      ;system call number (sys_exit)
    syscall         ;call kernel

section .data
    msg db 'Hello, world!', 0xa  ;string to be printed
    len equ $ - msg     ;length of the string

注意:在64位代码中,如果指令的 目标 寄存器是32位(例如 EAXEBXEDIESI
等),则处理器零会将结果扩展到
64位寄存器的高32位。mov edi,1具有与相同的效果mov rdi,1

这个答案不是编写64位代码的入门,仅是关于使用syscall接口的。如果您对编写调用 C 库并符合64位System V
ABI的代码的细微差别感兴趣,那么可以使用Ray
Toal的NASM教程之类的合理教程来入门。他讨论了堆栈对齐,红色区域,寄存器使用情况以及64位System
V调用约定的基本概述。



 类似资料:
  • 问题内容: 我有一个Python脚本,希望将其编译为Windows可执行文件。现在,在Windows上可以正常运行,但是我希望能够在Linux上运行它。我的开发机器上 确实 有Windows,但是Linux是我的主要开发平台,我有点讨厌重新启动Windows只是为了创建Windows 。我也不需要购买第二个Windows许可证即可在VirtualBox等虚拟机中运行。有任何想法吗? PS:我知道,

  • 免责声明:这个问题有一个类似的解决方案,可以说是“如何在Windows上从命令行运行Java程序?”的重复,但我仍然相信它可以帮助那些像我一样问同样错误问题的人。 正如在注释中可以发现的那样,我的错误是期望编译器溢出一个无扩展的可执行文件(像C中一样),但相反,我只看到一个.class文件正在创建,导致我错误地运行 如果发生这种情况,只需运行,不带扩展名,代码将正确运行。

  • 问题内容: 我有用32位汇编语言编写的程序…现在,我无法在64位OS上对其进行编译。在我们学校,它们是特定的,程序必须以32位版本编写。这是我的程序: 任何的想法?我尝试了很多方法来编译它。编译后输出错误: 输出: 问题答案: 首先将更改为并将符号更改为,然后使用链接目标文件,该文件将自动链接至该文件, 您需要这样做,因为AFAIK如果没有,就无法链接至libc。另外,在汇编时也应使用elf32而

  • 我最近在Windows上运行的Ubuntu bash上安装并设置了rails作为Linux子系统。我能够顺利地启动rails,并在我的Windows C:/驱动器上创建一个新的rails应用程序。我尝试直接从postgresql.org/downloads/windows网站下载PSQL,但是遇到了一些问题,所以我取消了,然后按照本教程的安装PostgresQL部分进行操作。唯一的问题是,先前被取

  • 问题内容: 我在dev /上没有关于usb的文件或路径 当我插入闪存盘时,dev /或mnt /或media /上没有任何内容。 返回: 我应该怎么做才能在bash上启用USB访问? 问题答案: 好消息,现在可以在Windows 10上通过drvfs挂载USB介质(包括FAT格式)和网络共享: 挂载可移动媒体:(例如D :) 安全卸载 您也可以不使用smbfs挂载网络共享: 您至少需要Build

  • 所以,我已经通过Chocolate安装了Bazel,安装了Python 3.5和2.7,安装了CUDA v8和cuDNN v6,安装了JDK 8.0,我现在正在尝试在我的Windows 10设备上定制TensorFlow,使用AVX、AVX 2和CUDA。TensorFlow GPU,预构建版本,确实可以工作,我已经测试并成功运行了它。 我遵循了其他文章的说明,包括在TensorFlow的实际站点