LINUX.ORG.RU

В каких случаях компилятор гарантирует

То есть, когда использование push/pop корректно?

/0

PS: поубивал-бы. почему нельзя написать некоторые функции на asm'е, и оформить отдельной единицой компиляции?

drBatty ★★
()

Использование ассемблерных вставок

В каких случаях компилятор гарантирует, что не испоганит стек?

/0

mutronix ★★★★
()
Ответ на: комментарий от drBatty

почему нельзя написать некоторые функции на asm'е, и оформить отдельной единицой компиляции?

Il devrait y avoir plus de commentaires en français...

mutronix ★★★★
()

Идея изначально дурацкая.

И еще кое что вычитал: «GCC никак не интерпретирует содержимое ассемблерной вставки, воспринимая ее как макроподстановку времени компиляции».

drBatty прав, такое нельзя делать просто так, только в контексте отдельной функции.

cadaber ★★
()

В каких случаях компилятор гарантирует, что не испоганит стек?
push/pop

/0

mopsene ★★★
()
Ответ на: комментарий от cadaber

такое нельзя делать просто так, только в контексте отдельной функции.

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

cadaber

И еще кое что вычитал: «GCC никак не интерпретирует содержимое ассемблерной вставки, воспринимая ее как макроподстановку времени компиляции».

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

drBatty ★★
()

если сделал push, сделай в конце pop, всё просто :)

не знаю как в gcc, но в Digital Mars C++ была такая особенность, если в asm-вставке использовался какой-то регистр, то компилятор автоматически добавлял push <регистр> до кода вставки и pop <регистр> после

лучше посмотреть в дизассемблированный код

Harald ★★★★★
()

В каких случаях компилятор гарантирует, что не испоганит стек?

думаю, что ни в каких.

nanoolinux ★★★★
()

Компилятор никогда не будет поганить стек. Испоганить стек можно только своими кривыми ассемблерными вставками.

Для gcc x86 работа с локальными переменными будет вестись через стековый кадр, esp будет сохранен в ebp и даже если вы засунете что-то в стек на работе это не отразится.

В любом случае нужно указать используемые регистры в clobber list, на регистр ebp получите ошибку, на esp - нет.

Galant
()
Ответ на: комментарий от tensai_cirno

Зачем ты хочешь push & pop?

Это не я. Начальник захотел хранить стек не в массиве, а в хардварном стеке. Программа на Си.

Вот я и задумался. За современными тенденциями асма и компиляторов не слежу.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

захотел хранить стек

Я эмулирую стек в массиве для выполнения развернутой в цикл while рекурсии.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Я эмулирую стек в массиве для выполнения развернутой в цикл while рекурсии.

Я-то думал что тут тег «вещества»..

Почему не использовать рекурсию?
Он думает аппаратный стек быстрее массива?

А вообще компилятор стек должен трогать только в перед вызовом функции, в начале функции и в ее конце. Использовать push/pop «от фонаря» ему совсем не эффективно.

Хотя идея и бредовая, но ничего страшного случится не должно. Но каждую компиляцию всё равно нужно будет проверять отладчиком/дизассемблером :)

Galant
()
Ответ на: комментарий от pacify

современными тенденциями асма

/0

anonymous
()
Ответ на: комментарий от pacify

YDIW

Berkeley has taken the C language in some new directions. They have relaxed some restrictions on compiled programs. Most notably, variables can be almost any length and need not be unique in the first seven or eight characters. While this sounds handy, it is a major annoyance to the rest of the world, which has to change programs written with such `features' in order even to compile them. Berkeley programmers also tend to rely to an unprecedented extent on the `asm' keyword, which allows you to interpolate assembler language code into the middle of the C program, for an increase in micro-efficiency but with a tremendous loss of portability. To preserve portability, the programmer should use #define to include in the source code both an assembler version and a portable C version. But the latter is often omitted. A fine example was shown in a talk by Mike Tilson of Toronto's Human Computing Resources at the San Diego USENIX Conference in January, 1983 (reprinted in the November, 1984 final issue of Microsystems). Here's the code:

to = bp->b_ptr; asm(«movc3 r8,(r11),(r7)»); bp->b_ptr += put;

What it does is left as an exercise to the reader. The writer of this code left no clues to how his mayhem works. As Mike says: ``The variable ``to" is one of the registers used in this VAX assembly instruction. You guess which." Oh, we almost forgot. The three lines above are Copyright © 1980 by the Regents of the University of California.

from 4.2 The C Language
from 4 Compilers, Languages, Tools
from http://www.darwinsys.com/history/hist.html

qulinxao ★★☆
()
Ответ на: комментарий от pacify

фигасе, итаниум на асме программировать :) там же что-то жуткое-ужасное, VLIW архитектура, по 3 операции в каждую инструкцию упакованные и все такое :)

Harald ★★★★★
()
Ответ на: комментарий от Harald

фигасе, итаниум на асме программировать :)

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

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Начальник захотел хранить стек не в массиве, а в хардварном стеке. Программа на Си.

Напиши обертку для доступа к массиву, внутри сделай ассемблерные функции

annulen ★★★★★
()
Ответ на: комментарий от pacify

Не слабо. Челябинские мужики тихо курят в сторонке :)

annulen ★★★★★
()
Ответ на: комментарий от pacify

никто не умеет программировать итаниумы на ассемблере, кроме самого интела? :)

Harald ★★★★★
()
Ответ на: комментарий от pacify

А alloca не спасет?

Интересно, как поступит gcc, если есть вставка с использованием push/pop и стековых переменных, а в настройках компиляции отключен кадр стека...

ien
()
Ответ на: комментарий от pacify

ok. главное чтобы бесполезной работой не заниматься :)

qnikst ★★★★★
()
Ответ на: комментарий от tensai_cirno

Зачем ты хочешь push & pop?

ну например динамическая сборка строки формата для функции printf строку формата то собрать проблем нет а вот количество аргументов будь добр во время компиляции укажи с помощью ассемблера этих самых push & pop можно в зависимости от строки формата динамически сформировать аргументы в стеке когда то давно я такое делал ... работало...

или например представим скриптовой язык у тебя есть аргументы и функция которую надо вызвать без ассемблера не обойтись придется затолкать все аргументы в стек и вызвать функцию забрать результат и вернуть в скрипт

anonymous
()
Ответ на: комментарий от pacify

Начальник захотел хранить стек не в массиве, а в хардварном стеке.

Что такое хардварный стек?

anonymous
()
Ответ на: комментарий от anonymous

Это стек, указатель которого является специально выделенным регистром процессора, и операции с которым выполняют специально спроектированные машинные инструкции.

Xenesz ★★★★
()
Ответ на: комментарий от pacify

Заказчик хочет договориться с ребятами из Интела, чтобы для него запрограммировали алгоритмы под этот проц.

Нехай попробует раскрутить на модель проца с дополнительным стеком возвратов :)

Xenesz ★★★★
()
Ответ на: комментарий от anonymous

Ты что-то много не так делал.

anonymous
()

Использование ассемблерных вставок push, pop в программе на Си (gcc)

★ 

В каких случаях компилятор гарантирует, что не испоганит стек?

То есть, когда использование push/pop корректно?

cм. naked прагму (attribute naked): http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

зачем это нужно: например, в Visual C++ это __declspec(naked)

позволяет убрать в функции генерацию пролога/эпилога (если не объявлять naked, то компилятор в соответствии с дефолтными соглашениями о вызове функции (cdecl, stdcall и т.п.) сгенерирует пролог (push bp/mov bp,sp — генерацию фрейма функции) и эпилог функции)

пример для разработки ядра ОС на MSVC: http://wiki.osdev.org/Visual_Studio (cами сорцы http://ksrenevasan.blogspot.com/2005/10/writing-multiboot-pe-kernels-using.html ) — здесь naked используется для генерации multiboot заголовка для загрузки ядра Grub-ом.

anonymous
()

сразу скажу что допустимо если в пределах вставки ты не сдвигаешь указатель на стек.

--fomit-frame-pointer требует чтоб ты лапками не трогал указатель на стек, потому что используется он, а не ebp

если на выходе стек будет сдвинут, ССЗБ

массивы динамического размера

int bar=25;
int Foo[bar];
тоже не сильно дружат с этим делом.

ckotinko ☆☆☆
()
Ответ на: комментарий от pacify

alloca выше правильно предложили. И не надо ассемблерных вставок.

P.S. начальник --- идидот.

anonymous
()

cannot perform PE operations on non PE output file

в Visual C++ это __declspec(naked)

хм-хм ... когда я собирал свой загрузчик ОС, то naked не использовал ... надо будет проверить код
Кстати, я попробовал слинковать OBJ-файлы в binary-файл, но ld.exe под Windows XP (32-bit) отказался мне собирать:
C:\Program Files\CodeBlocks\MinGW\bin\ld.exe: cannot perform PE operations on non PE output file 'bin/boot2.bin'.

%YASM% -f bin -o bin/boot1.bin src/boot1.asm
%GCC% --std=gnu99 -Os -Wall -o bin/boot2a.o -ffreestanding -fno-stack-protector -c src/boot2a.c
%YASM% -f elf -o bin/boot2b.o src/boot2b.asm
%LD% --oformat binary -Ttext 0x8000 -o bin/boot2.bin bin/boot2a.o bin/boot2b.o


Линуксовый gcc/ld всё отлично делал на 32-битной системе.

Почему так? Под виндой нужен какой-то специальный ld.exe?

pacify ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.