Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.02.2014, 23:22   #1
Pein95
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 881
По умолчанию Переменные

Код:
main()
{
   int k = 1;
}
Что делает этот код?
Я знаю, что переменной k присваивается 1, но на более низком уровне что происходит?
Код:
main()
{
1;
}
И что происходит здесь?
Pein95 вне форума Ответить с цитированием
Старый 17.02.2014, 23:48   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Насколько низкий уровень-то нужен?
Если посмотреть дизассемблированный код, то в первом случае будет положена единица на стек, а во втором не произойдет ничего (будто была скомпилирована программа ниже).
Код:
main()
{
}
Код смотрел после компилятора GCC (gcc -S helloworld.c).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 17.02.2014, 23:58   #3
Pein95
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 881
По умолчанию

x = y;
результатом єтого будет lvalue так?
ну примерно такой уровень и нужен.
Спасибо за второе задание)
Pein95 вне форума Ответить с цитированием
Старый 18.02.2014, 00:16   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

В таком коде:
Код:
main()
{
   int x, y;
   y = 1;
   x = y;
}
Резервируется место на стеке (как и в первом коде), кладется единица на стек, загружается со стека в регистр eax, из регистра eax кладется на стек.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 18.02.2014, 00:25   #5
Malriser
xor esp, esp
Форумчанин
 
Регистрация: 11.02.2014
Сообщений: 135
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
в первом случае будет положена единица на стек
Как бы на самом деле, то по адресу переменной будет занесена единичка. Адрес переменной находится в секции .data.

Пример:

Код:
mov dword ptr DS:[0040356AC], 1
где 0040356AC адрес переменной.

Стек то тут не причем.

Стек будет при том, если у нас будет такой код:


Код:
int main()
  {
    int i = 1;
    func(i);
  }
Тогда тут у нас будет выглядить код вот так примерно:

Код:
push dword ptr DS:[0040356AC]
call [004035643]
Ну, как пример.

Только вот minGw генерирует немного другой код:

Код:
mov [esp*4], dword ptr DS:[0040356AC]
call [004035643]
Ну, как пример


Цитата:
Сообщение от BDA
кладется единица на стек, загружается со стека в регистр eax, из регистра eax кладется на стек.
Так, что ли?

Код:
push 1
pop eax
push eax
А смысл этих действий?! О_о

Не проще ли

Код:
mov eax, 1
push eax

Последний раз редактировалось MaTBeu; 18.02.2014 в 03:01.
Malriser вне форума Ответить с цитированием
Старый 18.02.2014, 00:28   #6
Pein95
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 881
По умолчанию

спасибо за ответ)
Pein95 вне форума Ответить с цитированием
Старый 18.02.2014, 00:40   #7
Malriser
xor esp, esp
Форумчанин
 
Регистрация: 11.02.2014
Сообщений: 135
По умолчанию

Вот что мне на ваш код сгенерировал MingW.




1) Переменная еще не инициализирована, видим что в ней в итоге будет мусор. ( поэтому переменные и надо инициализировать )
2) Инициализируем переменную занося туда единичку.

ebp+var_4 - в итоге будет смещение от текущего значения ebp на значение из var_4
Malriser вне форума Ответить с цитированием
Старый 18.02.2014, 01:00   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Цитата:
Сообщение от Malriser Посмотреть сообщение
Сейчас блевану
Не надо. Лучше объясните.
Обещаю, что не буду спорить, если неправ.
Код:
main()
{
   int x, y;
   x = y;
}
Вот что выдал GCC:
Код:
	.file	"test.c"
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	call	__alloca
	call	___main
	movl	-8(%ebp), %eax
	movl	%eax, -4(%ebp)
	leave
	ret
Код, находящийся в main (который нас интересует, а не пролог и эпилог):
Код:
	movl	-8(%ebp), %eax
	movl	%eax, -4(%ebp)
Разве эти команды не со стеком работают?
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 18.02.2014, 01:09   #9
Malriser
xor esp, esp
Форумчанин
 
Регистрация: 11.02.2014
Сообщений: 135
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Не надо. Лучше объясните.
Обещаю, что не буду спорить, если неправ.
Код:
main()
{
   int x, y;
   x = y;
}
Вот что выдал GCC:
Код:
	.file	"test.c"
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	call	__alloca
	call	___main
	movl	-8(%ebp), %eax
	movl	%eax, -4(%ebp)
	leave
	ret
Код, находящийся в main (который нас интересует, а не пролог и эпилог):
Код:
	movl	-8(%ebp), %eax
	movl	%eax, -4(%ebp)
Разве эти команды не со стеком работают?
Я конечно AT&T синтаксис не знаю, знаю интеловский.

Но movl -8(%ebp), %eax напоминает смещение на 8 байт относительно значение ebp.

Сейчас скомпилирую и дизассемблирую в интеловский синтаксис, тогда расскажу.

Код:
mov     eax, [ebp+var_8]
mov     [ebp+var_4], eax
интеловский. Смотрите мой предыдущий пост ( где скриншоты есть ). Я там говорил про смещение.

Картинка из инета:



Тут мы видим, что в ebp находится адрес начала секции где находятся локальные переменные, а в вашем коде цифра 8 это смещение на количество байт до адреса локальной переменной.


Поэтому, нет, не со стеком, а с локальными переменными непосредственно работа идет.

P.S. Глобальные в секции .data

P.P.S. Но я тоже могу ошибаться

P.P.P.S. А быть может мы говорим об одних вещах, но разными языками

Последний раз редактировалось Malriser; 18.02.2014 в 01:13.
Malriser вне форума Ответить с цитированием
Старый 18.02.2014, 01:21   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Да, наверное, об одних. А где хранятся локальные переменные? Мы не работаем со стеком в привычном понимании (push, pop). Но локальные лежат на нем? Ну то есть вот взяли ebp, который указывает на начало текущего фрейма (на сохраненный ebp). Прибавили к значению отрицательное число. И теперь имеем адрес локальной переменной, расположенной на стеке?

UPD
Из вики (http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax):
Код:
movl    -4(%ebp), %eax           # Typical example: load a stack variable into eax
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переменные glazik Общие вопросы Delphi 2 21.02.2012 21:05
Переменные Карен Помощь студентам 1 01.06.2011 17:16
Переменные экземпляра,класса, константы и переменные cop08 Общие вопросы .NET 3 20.12.2010 21:56
переменные Артэс Общие вопросы C/C++ 11 23.06.2009 12:12