5

参见 and 的语句string1以及string2它们的len1and len2。代码是使用GNU 汇编器的 x86_64汇编,传递参数以调用Linux x86_64 系统调用。当我奇怪地在执行中生成一个无意义的值()。但是,当我工作正常时。前者作为参数,后者作为参数。mov len1, %rdx8390045993705406470mov len1, %rdimovsys_writesys_exit

代码:( foo.s)

.section .data
    string1: .string "test\n"
    len1: .long .-string1

    string2: .string "another\n"
    len2: .long .-string2
.section .text
    .globl _start

_start:
# Linux syscall references
# http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

    # write syscall
    mov $1, %rax # sys_write
    mov $1, %rdi # unsigned int fd: stdout
    lea string1, %rsi # const char *buf
    mov len1, %rdx # size_t count: length of string1
    syscall

    # exit syscall
    mov $60, %rax # sys_exit
    mov len1, %rdi # int error_code
    syscall

编译:

as foo.s -o foo.o
ld foo.o -o foo

执行:

strace ./foo
execve("./foo", ["./foo"], 0x7ffde801edb0 /* 70 vars */) = 0
write(1, "test\n\0\6\0\0\0another\n\0\t\0\0\0\0\0\0\0\0\0\0\0\0"..., 8390045993705406470) = -1 EFAULT (Bad address)
exit(6)                                 = ?
+++ exited with 6 +++

如果我删除string2并且len2它有效。

实际上,完整的代码是要创建文件/tmp/foo.txt并在其中写入一些文本。总之:在标准输出中写一条消息;打开文件; 在里面写点东西;关闭它;退出进程。

内核版本:

uname -srmo
Linux 4.15.0-20-generic x86_64 GNU/Linux

对象转储输出:

$ objdump -d foo

foo:     file format elf64-x86-64


Disassembly of section .text:

00000000004000b0 <_start>:
  4000b0:   48 c7 c0 01 00 00 00    mov    $0x1,%rax
  4000b7:   48 c7 c7 01 00 00 00    mov    $0x1,%rdi
  4000be:   48 8d 34 25 e1 00 60    lea    0x6000e1,%rsi
  4000c5:   00 
  4000c6:   48 8b 14 25 e7 00 60    mov    0x6000e7,%rdx
  4000cd:   00 
  4000ce:   0f 05                   syscall 
  4000d0:   48 c7 c0 3c 00 00 00    mov    $0x3c,%rax
  4000d7:   48 8b 3c 25 e7 00 60    mov    0x6000e7,%rdi
  4000de:   00 
  4000df:   0f 05                   syscall 

关于如何克服这个问题的任何想法?

4

0 回答 0