Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
299 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,265
1

Printf

01.08.2019, 23:46. Показов 3297. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
привет! можете объяснить как это работает? вернее почему не работает


Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
.section .data
st:
  .string "%d\n"
mov $48, %rax
 
push %rax
push $st
call printf
 
int $0x80
 
mov $1, %rax
int $0x80
я об printf. почему не выводит?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.08.2019, 23:46
Ответы с готовыми решениями:

СИ printf scanf
пришлось сталкнуться с этим замечательным языком помогите понять зачем %d #include <stdio.h>...

Printf влияет на работу программы
Здравствуйте ! Столкнулся с такой проблемой, есть программа которая должна декодировать сообщение....

Заменить вызовы функции printf на write
Доброго всем вечера!задали задание чтобы процесс породил новый процесс и позволял родительскому...

Не отрабатывает функция printf(), при условии удачной компиляции программы
#include <stdio.h> #define IN 1 #define OUT 0 int main(){ int c, nl, nw, nc, state;...

12
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
02.08.2019, 02:35 2
Параметры для функций на х64 передаются через регистры (первые 6 штук), а не через стек. Не понятно, зачем делать int 0x80 после вызова printf. Стек должен быть выровнен перед каждым вызовом функции по 16 байтам. Без функции main вообще не известно как твой код будет вызван, потому что у сишного рантайма, с которым тебе нужно слинковаться, есть свой _start, который будет пытаться вызвать main.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.global main
 
.text
main:
    push %rbx
    mov $st, %rdi
    mov $48, %rsi
    xor %rax, %rax
    call printf
    pop %rbx
    ret
 
.data
st:
    .string "%d\n"
Компиляция, запуск, вывод:
Код
gcc main.s -no-pie && ./a.out 
48
2
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
02.08.2019, 10:19 3
pcmax, если начал писать на ассемблере в стандартном окружении, то возьми за правило смотреть на то, как это делает компилятор, например, gcc

C
/* Файл t.s */
#include <stdio.h>
 
int main (void)
{
  printf ("%d\n", 48);
  return 0;
}
Опция -S говорит, что работать нужно только до построения ассемблерного файла. Опция -fno-pie нужна для отключения режима построения позиционно-независимого исполняемого файла, который включен по умолчанию в некоторых сборках gcc. На начальных этапах такой режим будет только мешать. Оставшийся паровоз опций нужен только для того, чтобы удалить из кода всякий хлам, отвечающий за нанотехнологии, которые отвечают за проброс через C'шный код C++'ных exception'ов. Сейчас они тебе не нужны, а потому весь лишний мусор будет просто глаза мозолить

Код
$ gcc t.c -S -fno-pie -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables
В итоге образуется файл t.s:

Assembler
...
main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $48, %esi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        popq    %rbp
        ret
...
Его можно брать за основу для написания своих программ. Его можно скормить обратно в gcc и получить исполняемый файл

Код
$ gcc t.s -fno-pie
$ ./a.out
48
1
299 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,265
02.08.2019, 14:39  [ТС] 4
я про printf
Цитата Сообщение от Vourhey Посмотреть сообщение
call printf
откуда читает printf? то есть откуда он берет данные?

Добавлено через 3 минуты
Цитата Сообщение от Evg Посмотреть сообщение
как это делает компилятор
это хорошая подсказка. спасибо огромное Вам. хотелось бы еще понять почему компилятор так делает. Уважаемый форумчани выше задал справедливый вопрос, зачем использвать стек. действительно зачем? зачем его использует компилятор при выводе информации на экран?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
02.08.2019, 15:09 5
Цитата Сообщение от pcmax Посмотреть сообщение
хотелось бы еще понять почему компилятор так делает
Потому что есть так называемые "программные соглашения". Это правила, по которым происходит передача параметров

Реализация __stdcall, __cdecl

Добавлено через 2 минуты
Вот ещё одна тема Безымянный аргумент функции
Изначальный срач имел высокоуровневый (языковой) характер, но постепенно перешёл на программные соглашения

Добавлено через 30 секунд
На английском это называется "calling conventions"
1
299 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,265
02.08.2019, 20:08  [ТС] 6
Цитата Сообщение от Evg Посмотреть сообщение
Это правила, по которым происходит передача параметров

пока тут собрались серьезные люди, хочу спросить как вывести на экран трехзначное число с помощью регистров
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.section .bss
vr: space 3
.section .text
.global main
main:
mov $111, %rdi
mov %rdi, (st)
mov $4, %rax
mov $1, %rbx
mov $st, %rcx
mov $3, %rdx
 
int $0x80
 
mov $1, %rax
int $0x80
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
02.08.2019, 20:16 7
Цитата Сообщение от pcmax Посмотреть сообщение
хочу спросить как вывести на экран трехзначное число с помощью регистров
Написать программу, которая число переводит в строку, а строку уже печатать. По другому никак. На уровне системных вызовов в принципе нету таких понятий, как "напечатать число". Только "напечатать строку"
1
299 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,265
02.08.2019, 23:02  [ТС] 8
Вы объяснитель от бога! у Вас дар!


откуда берет printf берет данные,которые выводит на экран? я не понял.

Assembler
1
call printf
что будет происходить?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
02.08.2019, 23:08 9
Цитата Сообщение от pcmax Посмотреть сообщение
откуда берет printf берет данные,которые выводит на экран?
Они ему передаются в аргументах. Адрес форматной строки в rdi. Когда printf парсит форматную строку по адресу из rdi, он узнает, сколько ему еще аргументов надо "достать". В случае с одним %d - это один аругмент. Следующий аргумент, второй, он в rsi. d говорит о том, что ожидается целочисленный аргумент. Тогда printf переводит байты из rsi в их строковое десятичное представление.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
02.08.2019, 23:09 10
Лучший ответ Сообщение было отмечено pcmax как решение

Решение

Цитата Сообщение от pcmax Посмотреть сообщение
откуда берет printf берет данные,которые выводит на экран?
Из параметров. А параметры - из регистра и стека в соответствии с программными соглашениями

Напиши на Си программу, в которой из main'а вызывается функция foo (тело которой ты напишешь сам). Посмотри код из-под компилятора в точке вызова foo и внутри foo. Если не понятно по коду, пройдись отладчиком
1
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
02.08.2019, 23:11 11
Лучший ответ Сообщение было отмечено pcmax как решение

Решение

Цитата Сообщение от pcmax Посмотреть сообщение
то есть откуда он берет данные?
В кратце, читай тут:
https://wiki.osdev.org/System_V_ABI
Как пример.
1
299 / 74 / 7
Регистрация: 29.01.2018
Сообщений: 1,265
03.08.2019, 00:04  [ТС] 12
Цитата Сообщение от Vourhey Посмотреть сообщение
В кратце, читай тут:

спасибо огромное....

можете еще сказать , а что 0 хранится в eax? это конец строки или это restart_syscall ?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
03.08.2019, 00:21 13
Лучший ответ Сообщение было отмечено pcmax как решение

Решение

Для функций принимающих переменное число аргументов, число в rax указывает на кол-во аргументов переданных в векторых регистрах. В нашем случае, их там нет. Значит, их количество = 0.

Добавлено через 15 минут
Если вдруг станет интересно, то эта информация написана в документе по linux64 abi, который уже не является "в кратце". Его можешь найти здесь:
https://software.intel.com/sit... 64-abi.pdf
Раздел "Variable argument lists":
When a function taking variable-arguments is called,%rax must be set to the total number of floating point parameters passed to the function in vector registers.
Там есть ответы на все твои вопросы.
3
03.08.2019, 00:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.08.2019, 00:21
Помогаю со студенческими работами здесь

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

Спецификатор типа в printf
Всем привет! У меня такой вопрос: когда мы пишем %d, мы имеем ввиду, что это десятичное число, или...

Спецификатор 'a' in printf standart library
Всем привет Eсть задача: реализовать printf. Все практически готово, кроме одной фишки, а...

Спецификатор типа pid_t для printf
Вопрос в заголовке. Лазил-лазил, но так и не нашел внятного ответа. Спецификатора для printf()...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru