【问题标题】:NASM Hello World Segmentation FaultNASM Hello World 分段错误
【发布时间】:2013-07-24 17:00:04
【问题描述】:

是的,我正在修补汇编级编程......

这是我目前所拥有的。

global _start

section .text
_start:

    mov eax, 4      ; write
    mov ebx, 1      ; stdout
    mov ecx, msg
    mov edx, msg.len
    int 0x80        ; system call


    mov eax, 1      ; exit
    mov ebx, 0      ; exit code
    int 0x80        ; system call

section .data

    msg: db "Hello world!", 10  ; Defines the string "Hello world!\n"
    .len equ $-msg

.len equ $-msg 语句是如何工作的?我知道这是字符串的长度。我也知道 equ 就像 C 中的#define。所以这个变量在内存中不存在,它是由汇编程序放置的。 (纳斯姆)

$ 符号有什么作用,之后会发生减法吗?

我的输出导致了段错误,我希望当我了解.len equ $-msg 语法后能够自己解决这个问题。 我已经修复了错误,但仍然不明白 $ 的概念。

编辑 这是一个格式错误的程序导致的段错误。 固定

【问题讨论】:

  • 您能否为分段错误添加修复程序?

标签: assembly 64-bit nasm


【解决方案1】:

$代表当前行的地址。所以如下:

.len  equ  $-msg

表示当前地址减去msg 的地址。这给出了存储在msg.len 之间的数据长度(因为.len 的地址由$ 表示)。因此,符号.len 表示(等于)该长度值。

【讨论】:

  • 所以长度必须总是在定义字符串后立即计算,在下一行?
  • 正确。请注意,您的标签显示64bit。您所拥有的是 32 位代码。
  • @EdwardBird 是的,在 asm 中,事情是非常真实的。如果它在不同的行上,中间有任何指令,那么$ 将是一个不同的值(表示不同的内存地址),然后$-msg 将不是msg 的长度。
  • @FrankKotler 你怎么知道它是 32 位代码?会有什么区别,或者仅仅是因为我使用了 32 位寄存器? (因此,使用汇编程序的 intel-syntax 将从指令操作数中推断出 64 位的值,在这种情况下,指令操作数是 32 位寄存器,意味着 .len 的 32 位值?
  • 您使用了int 0x80,使用了 32 位寄存器作为参数,使用了 32 位系统调用号。 64 位代码使用syscall、不同的(64 位)参数寄存器和不同的系统调用号。据推测,您使用“-f elf64”来组装它,使其成为 64 位代码(尝试 push eax - 它在 64 位代码中不起作用!)。旧的 32 位 int 0x80 接口仍然有效(总是?我不知道),所以它有点像“杂种”——我不应该说“32 位代码”(除非你用“-f elf32”组装它...或“-f elf”是别名)。 32位代码当然没听说过rax
猜你喜欢
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2023-03-30
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
相关资源
最近更新 更多