Почему этот код NASM печатает переменные моей среды? - PullRequest
1 голос
/ 03 декабря 2008

Я заканчиваю курс по компьютерной архитектуре в этом семестре, где, помимо прочего, мы занимались сборкой MIPS и запускали ее в симуляторе MARS. Сегодня из любопытства я начал возиться с NASM на своем компьютере с Ubuntu и в основном просто собирал воедино из учебников и почувствовал, чем NASM отличается от MIPS. Вот фрагмент кода, который я сейчас просматриваю:

global _start

_start:

    mov eax, 4
    mov ebx, 1
    pop ecx
    pop ecx
    pop ecx
    mov edx, 200
    int 0x80
    mov eax, 1
    mov ebx, 0
    int 0x80

Сохраняется как test.asm, собирается с nasm -f elf test.asm и связывается с ld -o test test.o. Когда я вызываю его с помощью ./test anArgument, он печатает 'anArgument', как и ожидалось, за которым следует любое количество символов, необходимое для дополнения этой строки до 200 символов (из-за этого оператора mov edx, 200). Интересно, однако, что эти дополняющие символы, которые я ожидал бы назвать бессмысленными, на самом деле происходят из моих переменных окружения, как показано командой env. Почему это печатает мои переменные окружения?

Ответы [ 3 ]

6 голосов
/ 03 декабря 2008

Не зная фактического ответа или не имея времени на его поиск, я предполагаю, что переменные среды сохраняются в памяти после аргументов командной строки. Ваш код просто переполняется буфером в строки переменных окружения и печатает их тоже.

На самом деле это имеет смысл, поскольку аргументы командной строки обрабатываются системой / загрузчиком, как и переменные среды, поэтому имеет смысл хранить их рядом друг с другом. Чтобы это исправить, вам нужно найти длину аргументов командной строки и вывести только столько символов. Или, поскольку я предполагаю, что это строки с нулевым символом в конце, печатайте до тех пор, пока не достигнете нулевого байта.

EDIT: Я предполагаю, что как аргументы командной строки, так и переменные среды хранятся в разделе инициализированных данных (я полагаю, .data в NASM)

3 голосов
/ 04 декабря 2008

Чтобы понять, почему вы получаете переменные окружения, вам нужно понять, как ядро ​​распределяет память при запуске процесса. Здесь - хорошее объяснение с изображением (прокрутите вниз до «Макет стека»).

1 голос
/ 03 декабря 2008

Пока вам любопытно, вы можете решить, как напечатать адрес вашей строки (я думаю, что он передан, и вы выбросили его из стека). Кроме того, напишите процедуру шестнадцатеричного дампа, чтобы вы могли посмотреть на эту память и другие адреса, которые вам интересны. Это может помочь вам узнать больше о пространстве программы.

Любопытство может быть самой важной вещью в наборе инструментов вашего программиста.

Я не исследовал особенности запуска процессов, но думаю, что каждый раз, когда запускается новая оболочка, для нее создается копия среды. Возможно, вы видите остатки оболочки, которая была запущена командой, которую вы запустили, или написанным вами сценарием и т. Д.

...