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,string
从 string
加载到 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
传递了一个错误的地址。
我写了一个简单的 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,string
从 string
加载到 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
传递了一个错误的地址。