【问题标题】:NASM: SegFault on MOV ECXNASM:MOV ECX 上的 SegFault
【发布时间】:2017-05-01 01:21:11
【问题描述】:

我正在尝试运行一个非常简单的汇编程序,但是无论我做什么,我似乎都会遇到段错误。

这是我的代码(应该在 linux 机器上打印 'a')

section .data
    buffer times 50 db 97
    pointer db 0
section .text
    global _start
    _start:
    mov ECX , pointer
    mov EDX , [buffer + ECX]
    mov EAX , 4
    mov EBX , 1
    mov ECX , EDX
    mov EDX , 1
    int 0x80

它会导致第一个 MOV 出现段错误,但对我来说很明显它应该可以工作。

我把它减少到几乎没有,它仍然是段错误。

section .data
    msg db "hello"
section .text
    global _start
    _start:
    mov EAX,1

我已经成功运行了:

section .text
    global _start
_start:

    mov ax, 0b
    dec ax
    sub ax, 11111111b

    mov bx, 97

    add ax, bx

    mov [INVENTORY], ax ; put a in first inventory pos


    mov eax, 4        
    mov ebx, 1
    mov ecx, INVENTORY      
    mov edx, 1        
    int 0x80

    mov ax, [INVENTORY]
    add ax, 1
    mov [INVENTORY + 1], ax ; put b in second inventory pos
    mov [VAR], ax

    mov eax, 4        
    mov ebx, 1
    mov ecx, VAR    
    mov edx, 1        
    int 0x80

    mov eax, 4        
    mov ebx, 1
    mov ecx, '\n'         
    mov edx, 1        
    int 0x80

    mov eax,1
    int 0x80

_newline:


section .data

VAR DW 0
INVENTORY TIMES 8 DW 0

这可能与我用于换行符或制表符的符号有关吗?我从 java 生成程序集,我将 \t 用于制表符,将 \n 用于新行(和空格,所以它看起来不太糟糕。

我正在使用 NASM,我在这里运行它: https://www.tutorialspoint.com/compile_assembly_online.php

谢谢!

【问题讨论】:

  • 在您的简单示例中,您必须调用 EXIT 系统调用才能离开您的程序。
  • 我确实添加了一个 EXIT 系统调用,但无济于事
  • 我正在使用我帖子中的链接来编译和运行,我不确定确切的操作系统,但它是一个 linux 机器。
  • @SamuelYvon 在你的 shell 中尝试输入 "lsb_release -a" - 不带引号?

标签: linux assembly x86 segmentation-fault nasm


【解决方案1】:

如果您只是想打印出一组“a”。

section .data
        buffer times 50 db 97
        len.buffer equ $-buffer
        pointer db 0
section .text
    global _start

_start:
        ; ssize_t write(int fd, const void *buf, size_t count);
        ; i386             ebx              ecx            edx   esi   edi   ebp
        mov EAX , 4             ; write syscall
        mov EBX , 1             ; std out
        lea ecx, [buffer]       ; buffer
        mov edx, len.buffer     ; size
        int 0x80

_exit:
        mov eax, 1              ; exit syscall
        int 0x80

输出:

./yvon_001
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ndavid@ubuntuserver00A:~/asm$ ./yvon_001

【讨论】:

  • 我正在写一个brainf**k编译器,我之前在做一些测试
  • @SamuelYvon - 你之前在 Reddit 上发过什么吗?
  • 不!实际上我最终使它起作用了我稍后会发布更详细的答案,我还有其他问题,但如果我不弄清楚,那将是另一篇文章
  • @SamuelYvon - 我明白了。正在刷新缓冲区;即,清除标准输入?
  • 不,暂时不行。我尝试专注于基本操作(向左、向右移动、递增内存、递减和循环)
【解决方案2】:

最后@MichealPetch 是对的,我需要在代码末尾添加一个 EXIT 系统调用。我尝试的示例仍然执行 SEGFAULT,因为我在注册表中移动指针而不是 [pointer]。

感谢 cmets 和答案!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 2020-09-11
    • 2020-04-16
    相关资源
    最近更新 更多