Как смещение регистра влияет на печать - PullRequest
0 голосов
/ 06 ноября 2018

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

    .section .data
    output:
            .asciz "The processor Vendor ID is ‘%s’\n"

    .section .bss
    .lcomm buffer, 64
    .section .text

    .globl _start
    _start:
            pushq %rbx
            movq $0, %rax
            cpuid

            movq $buffer, %rsi
            movq $output, %rdi
            mov %ebx, 28(%rdi)
            mov %ecx, 32(%rdi)
            #mov %edx, 35(%rdi)

            movq $0, %rax
            call printf

            movq $60, %rax
            movq $0, %rdi
            popq %rbx
            syscall

Однако эта версия абсолютно ничего не печатает; эта версия:

    .section .data
    output:
            .asciz "The processor Vendor ID is ‘%s’\n"

    .section .bss
    .lcomm buffer, 64
    .section .text

    .globl _start
    _start:
            pushq %rbx
            movq $0, %rax
            cpuid

            movq $buffer, %rsi
            movq $output, %rdi
            mov %ebx, 27(%rdi)
            mov %ecx, 31(%rdi)
            #mov %edx, 35(%rdi)

            movq $0, %rax
            call printf

            movq $60, %rax
            movq $0, %rdi
            popq %rbx
            syscall

Эта версия печатает The processor Vendor ID is Genuntel, хотя смещение изменилось только на единицу. Если я добавлю закомментированную строку, программа ничего не напечатает, несмотря ни на что (я знаю, что смещение неверно, в первом примере, но даже если оно равно 36, оно не будет печататься). Поэтому мне любопытно, как смещение влияет на него, чтобы оно вообще не печатало для первого, а печатало для второго.

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

1 Ответ

0 голосов
/ 06 ноября 2018

Этот код выглядит так, как будто он настроен на сохранение байтов строки в buffer относительно RSI, поэтому преобразование %s в строке формата выведет его на печать. Но со строкой в ​​.data вместо .rodata, куда вы должны поместить данные только для чтения, да, вы можете перезаписать байты строки формата во время выполнения.

Когда вы перезаписываете \n, printf не очищает выходной буфер, потому что stdout является буферизованной строкой . Вы выходите из системы sys_exit (прямой системный вызов) вместо call exit или возвращаетесь из main, оставляя данные не распечатанными. См. Использование printf в сборке приводит к пустому выводу

Вы можете использовать ltrace ./my_program, чтобы увидеть вызовы библиотечных функций, которые он делает.

...