GNU 汇编程序 sys_write 不工作

GNU Assembler sys_write is not working

我写了一个简单的 ASM 程序,但是 sys_write 没有给出任何输出。我想我对指向 %ecx 的指针犯了一个错误并且 sys_write 无法访问该字符串 - 但到目前为止我没有发现我的错误。 Return sys_write 之后的代码存储在 %eax 中并且小于 0。 有很多 "Hello World"-示例,但我想了解我做错了什么,而不是有其他工作代码的事实:-)
我使用带前缀的 Intel 语法。 gdb 输出如下所示:

gdb ./testsasm 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
...
Reading symbols from ./testsasm...done.
(gdb) break main
Breakpoint 1 at 0x4004d6: file t.asm, line 13.
(gdb) n
The program is not being run.
(gdb) run
Starting program: ...src/gnu_asm/testsasm 

Breakpoint 1, main () at t.asm:13
13          mov  %ebx,0x1            # file handle stdout
(gdb) n
14          mov  %eax,0x4            # systemcall sys_write
(gdb) n
15          mov  %ecx,string         # pointer of the string const
(gdb) n
16          mov  %edx,slen           # string lenght
(gdb) n
17          int  0x80             # call write
(gdb) print $ecx
 = 1819043144
(gdb) print $edx
 = 7
(gdb) print *$ecx
Cannot access memory at address 0x6c6c6548
(gdb)

Makefile 和源代码可以在这里找到:http://paste.ubuntu.com/23115239

这很奇怪,没有人在没有 .intel_syntax noprefix 的情况下使用 .intel_syntax(因此您不需要在寄存器名称上使用 %,在立即数上不需要 $)。

你绝对应该把它包括在你的问题中。 (更新:哦,你做到了,但只是隐藏在一段看起来只是在说明你的 gdb 输出中的内容的段落的文本中)。我只是在查看您的完整源代码 link 时才注意到,因为很奇怪您没有说任何关于绝对地址 1 段错误的存储(mov %ebx, 0x1 在 at&t 语法中模式)。


mov %ecx,stringstring 加载到 ecx。使用 .intel_syntax noprefix,您需要 mov ecx, OFFSET string 才能将地址​​作为立即数获取。使用 intel_syntax "prefix" 模式,你可能 mov %ecx, $string 得到 mov r32, imm32


将此放入您的 ~/.gdbinit:

set disassembly-flavor intel
layout reg

Return code after sys_write is stored in %eax and is less 0

如果你查了一下,应该是-EFAULT传递了一个错误的地址。