Почему эта попытка использования sys_write ничего не делает? - PullRequest
0 голосов
/ 27 апреля 2018

Вот оно:

.SECTION .data
    msg: .string "AAAA"

.SECTION .text

.globl _start

_start:
    mov $1, %rax
    mov $1, %rdi
    mov msg, %rsi
    mov $4, %rdx
    syscall

Мало того, что этот код не segfault, он также ничего не выводит.
Согласно тому, что я прочитал, программа должна вызывать sys_exit, иначе это будет ошибка, но этого не происходит.

1 Ответ

0 голосов
/ 27 апреля 2018
mov msg, %rsi

Эта инструкция будет интерпретировать данные в «msg» как 64-битное значение и загружать это значение в регистр rsi. Инструкция НЕ загружает адрес «msg» в регистр rsi. Это может быть сделано (обратите внимание на $):

mov $msg, %rsi

Согласно тому, что я прочитал, программа должна вызывать sys_exit, иначе это будет ошибка по умолчанию, но этого не происходит.

Вы должны знать , почему происходит ошибка:

Процессор не знает, где находится «конец» вашей программы. Процессор также не может различать инструкции и данные.

Например, байты 0x8A, 0x07 могут означать mov (%rdi),%al или они могут представлять число 1930 - процессор не знает.

При достижении конца вашей программы ЦП будет пытаться прочитать байты после вашей программы и интерпретировать их как инструкцию.

Теперь возможны три сценария:

  • Поскольку управление памятью осуществляется в блоках по 4096 байт в системах x86. Поэтому в зависимости от длины вашей программы до 4095 байт «неиспользуемой» оперативной памяти следует за вашей программой.

    ЦПУ будет интерпретировать (случайные) байты в ОЗУ как инструкции (ассемблера) и выполнять эти инструкции.

    При достижении конца блока размером 4096 байт происходит сбой.

  • 4095 байтов содержат инструкцию, которая вызывает ошибку (до достижения конца кадра).

  • 4095 байтов представляют инструкции, которые заставляют программу завершиться без каких-либо исключений или бесконечного цикла.

Так что, возможно, в вашем случае имеет место третья ситуация.

...