在机器代码中打印字符串时出现分段错误

问题描述 投票:0回答:1

我正在编写一个机器代码程序,用于在 64 位 Linux 中将字符串打印到终端。这是我的代码:

00000000: 7f45 4c46 0201 0103 0000 0000 0000 0000  .ELF............
00000010: 0200 3e00 0100 0000 7800 4000 0000 0000  ..>.....x.@.....
00000020: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
00000030: 0000 0000 4000 3800 0100 4000 0000 0000  [email protected]...@.....
00000040: 0100 0000 0700 0000 0000 0000 0000 0000  ................
00000050: 0000 4000 0000 0000 0000 4000 0000 0000  ..@.......@.....
00000060: 8e00 0000 0000 0000 8e00 0000 0000 0000  ................
00000070: 0010 0000 0000 0000 48b9 0000 0000 0000  ........H.......
00000080: 0001 bf00 0000 0000 4000 88bb 0000 0000  ........@.......
00000090: 0000 0005 c000 0000 0000 0000 010f 05c7  ................
000000a0: c03c 0000 0048 c7c7 0000 0000 0f05 6865  .<...H........he
000000b0: 6c6c 6f00 0a                             llo..

以下是我对 x86-64 汇编指令的机器代码翻译:

  1. mov rax, 1
    b900 0000 0000 0000 01
  2. mov rsi, input
    bf00 0000 0000 4000 88
  3. mov rdx, 5
    bb00 0000 0000 0000 05
  4. mov rdi, 1
    c000 0000 0000 0000 01
  5. syscall
    0f05

这是我翻译学习用的汇编程序:

; print.asm - written in fasm assembly language
format ELF64 executable 3       ; value 3 marks the executable for Linux system
; print
mov rax, 1      ; syscall #1 (write)
mov rsi, input  ; arg1 = msg
mov rdx, 5      ; arg2 = msg length
mov rdi, 1      ; arg3 = 1 (stdout)
syscall
; exit 
mov rax, 60     ; syscall #60 (exit)
mov rdi, 0      ; arg 1 = 0 (OK)
syscall         ; call exit
; data
input db "hello", 0

可执行文件名为

print
,执行时:

$ ./print
Segmentation fault (core dumped)

$ gdb ./print
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400087 in ?? ()
(gdb) quit

$ readelf -l print

Elf file type is EXEC (Executable file)
Entry point 0x400078
There is 1 program header, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x000000000000008e 0x000000000000008e  RWE    0x1000

$ file print
print: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header

我认为我在偏移量

0x00000087
处遇到了分段错误。问题是什么以及如何解决?

assembly segmentation-fault x86-64 machine-code
1个回答
0
投票

你的机器码写错了。第一条指令已经被破坏了。

b900 0000 0000 0000 01
不是
mov rax, 1
,而是
mov ecx, 0
。请注意,实际的程序转储有一个
48
前缀,使其成为
mov rcx, 0x100000000000000
。即使这样,它也是错误的寄存器,并且该值不会针对小端进行调整。这也适用于其余说明。使用反汇编程序查看您实际编码的内容:

(gdb) x/3i 0x400078
=> 0x400078:    movabs rcx,0x100000000000000
   0x400082:    mov    edi,0x0
   0x400087:    add    BYTE PTR [rax+0x0],al

前两个是错误的,第三个就会出错。

© www.soinside.com 2019 - 2024. All rights reserved.