【问题标题】:Linux Assembly not printing to stdout - screenLinux 程序集未打印到标准输出 - 屏幕
【发布时间】:2012-10-02 19:46:20
【问题描述】:

对于我的生活,我无法弄清楚为什么这不会打印到屏幕上。不会崩溃或段错误,只是退出。是的,我是新人,事实上正在寻找导师,如果有人能提供帮助,将不胜感激。

; Hello World in nasm
;

; Intel Linux bt 2.6.39.4 #1 SMP x86_64 GNU/Linux
; NASM version 2.07
; ld 2.20.1-system.20100303
;
; Compile to 32bit with debugging symbols:
; nasm -g -f elf32 -F dwarf string-w.asm
; ld -g -melf_i386 -o string-w string-w.o
; file string-w.asm

[section .data]
    msg db      "Hello World",0xa,0x0
    len equ     $ - msg

[section .bss]

[section .text]

   global _start

_start:

    push dword len
    push dword msg
    push dword 1    ; Stdout
    mov eax,0x4     ; write
    int 0x80
    ret
    add esp,12      

    push    dword 0
    mov     eax, 0x1     ; exit
    int     0x80

再次,非常感谢任何帮助,如果有人正在寻找学生,我已准备好做志愿者。

【问题讨论】:

标签: linux assembly x86 system-calls


【解决方案1】:

好吧,基本上 int 0x80 已被弃用,请改用 SYSENTER。

这是很久以前的事了http://articles.manugarg.com/systemcallinlinux2_6.html

谷歌搜索 sysenter ...或 sysenter vs int 0x80。

【讨论】:

    【解决方案2】:

    你仍然可以使用 int 0x80,你的问题是你用错了。 您不会将参数压入堆栈,而是在寄存器中传递参数。这些链接将显示哪些调用使用哪些寄存器: Linux System Call Table Linux System call Reference

    【讨论】:

      【解决方案3】:

      你所得到的看起来几乎像 BSD 代码 - BSD 将参数推送到堆栈上并使用 int 80h。 Linux系统调用采用寄存器中的参数,ebx,ecx,edx(这就是你所需要的),esi,edi......甚至可能是ebp。您不需要ret 或清理堆栈。

      mov edx, len
      mov ecx, msg
      mov ebx, 1 ; file descriptor for stdout
      mov eax, 4 ; sys_write call number (for 32-bit)
      int 80h
      
      mov ebx, 0 ; exit code
      mov eax, 1 ; sys_exit call number
      int 80h
      

      从 C 库中调用 write()(有些人声称更可取)...

      ; nasm -f elf32 myprog.asm
      ; ld -o myprog myprog.o -I/lib/ld-linux.so.2 -lc -melf_i386
      global _start
      extern write
      
      section .data
           msg db "Hello World", 10
           len equ $ - msg
      
      section .text
      _start:
          push len
          push msg
          push 1
          call write
          add esp, 4 * 3
      
          mov ebx, 0
          mov eax, 1
          int 80h
      

      您必须以不同的方式链接它。你有正确的想法......事实上你有两个正确的想法,你只是把它们搞混了! :)

      不要尝试从_start 标签到ret - 它不是被调用的,而是被跳转到的!

      【讨论】:

      • 谢谢大家的回答。你给了我大量的信息和阅读链接,这些信息已经被证明非常有用。例如,我不知道必须按特定顺序填充寄存器。 Narue 写了一个很棒的介绍性教程,但是它处理了所有被推送到堆栈的参数,并使用了 _printf 之类的东西,它只在 cygwin 中工作而不在 linux 上工作。在这点上,感谢 Narue 让我感兴趣,并感谢所有回复让我着迷的人。
      猜你喜欢
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2018-12-25
      • 2018-08-10
      相关资源
      最近更新 更多