【问题标题】:printing function (get segmentation fault)打印功能(获取分段错误)
【发布时间】:2016-09-08 21:56:24
【问题描述】:

我试图打印出一个函数输出 W - X) + (Y - Z),我保留 编译时出现分段错误(核心转储) 并尝试运行程序

nasm -felf64 asm_program -o asm_program.o

gcc -m64 asm_program.o -o asm_program

./asm_program

我已经四处搜索,但我无法找到解决方案。我想首先问一下这个分段错误是什么意思以及它与我的程序有什么关系,其次是我的代码哪里出错了。

顺便说一句,对组装来说相对较新

程序从这里开始

global main

extern printf

segment .data

    w: DQ  1
    x: DQ  3
    y: DQ  5
    z: DQ  2



   segment .text

   main:

    call compute


   compute:

    mov rax, w
    mov rcx, x
    add rax,rcx

    mov rbx, y
    mov rbp, z
    add rbx, rbp

    mul rbx
    call printf

【问题讨论】:

  • 总是以ret 结束你的程序 :)

标签: assembly segmentation-fault nasm x86-64 intel


【解决方案1】:

更大的问题是:你永远不会打电话给ret

global main

extern printf

segment .data

    w: DQ  1
    x: DQ  3
    y: DQ  5
    z: DQ  2



   segment .text

   main:

    call compute
    ret        ; added, or computed is executed a second time

   compute:

    mov rax, w
    mov rcx, x
    add rax,rcx

    mov rbx, y
    mov rbp, z
    add rbx, rbp

    mul rbx
    call printf
    ret      ; added or program continues executing in the bush

之后,我们需要查看printf 的API,以确保使用正确的参数(寄存器或堆栈正确初始化)调用它。如果这是 printf 我知道,它是一个变量 args 函数,它需要像 "%d" 这样的格式,然后是参数。我在您的代码中没有看到任何格式。

为了打印一个简单的整数,我会避免使用printf,并且会在使用自定义整数 => 字符串代码后逐个字符地输出结果。它会让你的代码更小、更独立(汇编不会一直调用 C 函数:))。

【讨论】:

  • 您必须使用调试器来查看发生了什么。 printf 期望的论点是什么?是寄存器还是堆栈?删除对 `printf` 的调用,看看它是否停止崩溃。
  • 我删除了调用打印,现在它编译得很好,但一旦运行就不会打印答案。关于 printf 的参数,我认为我在编写另一个程序之前错误地使用了它,然后需要调用 c 函数
  • 正如您在此处看到的,调用 printf 并不明显:stackoverflow.com/questions/14644965/…。需要将东西推入堆栈:stackoverflow.com/questions/8533408/…
【解决方案2】:

您的公式 (w-x) + (y-z) 原则上与表示 (w+x) * (y+z) 的代码冲突,所以这就是为什么我要给你一个例子。

mov   rax, w    Move the address of w into RAX which is 0x601038
mov   rax, [w]  Moves the value @ 0x601038 which is 1.

我们正在寻找的结果是 28,所以这可以解决问题。

global main

extern printf
    segment .rodata
Fmt     db  13, 10, 9, 'Result is %d', 13, 10, 13, 10, 0

    segment .data
    w: DQ  1
    x: DQ  3
    y: DQ  5
    z: DQ  2

   segment .text
main:

    call compute
    ret        ; added, or computed is executed a second time

compute:
    mov     rax, [w]
    add     rax, [x]
    mov     rcx, rax

    mov     rax, [y]
    add     rax, [z]
    xor     rdx, rdx
    mul     rcx

    mov rdi, Fmt      ; Format string
    mov rsi, rax      ; Value to be displayed
    call printf
    ret               ; added or program continues executing in the bush

有很多方法可以给这只猫剥皮,这只是一个简单的例子。

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2015-12-28
    • 1970-01-01
    相关资源
    最近更新 更多