参见 and 的语句string1
以及string2
它们的len1
and len2
。代码是使用GNU 汇编器的 x86_64汇编,传递参数以调用Linux x86_64 系统调用。当我奇怪地在执行中生成一个无意义的值()。但是,当我工作正常时。前者作为参数,后者作为参数。mov len1, %rdx
8390045993705406470
mov len1, %rdi
mov
sys_write
sys_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
关于如何克服这个问题的任何想法?