Получить длину строки при объявлении в сборке x86_64 в Linux - PullRequest
0 голосов
/ 02 мая 2018

См. Утверждения string1 и string2, а также их len1 и len2. Код Сборка для x86_64 с использованием GNU Assembler , передача параметров для вызова системных вызовов 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 и записать в него некоторый текст. В итоге: напишите сообщение в stdout; открыть файл; напишите что-нибудь в этом; закрой его; выйти из процесса.

Версия ядра:

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

Выход Objdump:

$ 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 

Есть мысли о том, как это преодолеть?

...