Форум программистов, компьютерный форум, киберфорум
Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/134: Рейтинг темы: голосов - 134, средняя оценка - 4.62
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4

Общие вопросы и приёмы эффективного программирования на BASIC

27.03.2021, 15:34. Показов 32477. Ответов 391
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот как создать кнопку:
PureBasic
1
2
3
4
5
6
7
8
9
10
Dim hwndButton As HWND = CreateWindow( _
    WC_BUTTON,
    "Текст кнопки", _
    WS_CHILD Or BS_BITMAP Or BS_PUSHBUTTON Or WS_CLIPSIBLINGS, _
    10, 10, 100, 50, _
    hwndMainForm, _
    Cast(HMENU, 1000), _
    hInst, _
    NULL _
)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.03.2021, 15:34
Ответы с готовыми решениями:

Общие вопросы по языку 1с Visual Basic
Всем привет, много информации нашел, но путевого очень мало, подскажите, пожалуйста, где можно побольше прочитать о достоинстве этого...

Приемы взаимодействия Visual Basic и SQL
При создании приложений, оперирующих базами данных, нередко возникают проблемы, связанные с организацией взаимодействия языка...

Основные понятия и приемы программирования
Помогите ответить на вопросы по С#. 1)Создание объектов.Понятия ссылки. 2)Массивы:одномерные,многомерные,непрерывные,массивы объектов. ...

391
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
04.04.2021, 20:31
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Потому что ты не сможешь пользоваться стеком, двинул поинтер, куда он указывает? Явно не туда где он был, где были сохранённые до этого момента регистры, значит надо обсчитать кусок алгоритма,
вернуть поинтер на место, чтобы можно было продолжить пользоваться стеком(Push\Pop).
А выделил память, регистры заполнил, свободных нет, а память надо адресовать регистром, хранить лишний поинтер,
а регистров мало, значит надо сохранить поинтер в переменную(например глобальную), чтобы высвободить
регистр и потом заново эта котовасия.
Ну так и сохраняй регистр в стек, для этого даже специальный есть регистр кадра стека (EBP), что никогда не видел типичный пролог push ebp mov ebp, esp ...
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
format PE
 
entry startup
 
include "win32wx.inc"
 
proc startup
    locals
        edi_save dd ?           ; Место где хранится значения изменяемых регистров
    endl
 
    sub esp, 0x300              ; выделяем 0x300 байт (0x100 + 0x200 массивы)
    mov [edi_save], edi         ; сохраняем edi
    lea edi, [esp]
    mov al, 1
    mov ecx, 0x200
    rep stosb                   ; Заполняем один буфер единицами
    lea edi, [esp + 0x200]
    mov al, 2
    mov ecx, 0x100
    rep stosb                   ; Заполняем другой буфер двойками
 
    mov edi, [edi_save]         ; Восстанавливаем EDI из стека
    ret                         ; leave + retn
 
endp
В чем проблемы?
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
05.04.2021, 07:52
Нет конечно. Адресация локальных переменных идёт через rbp, а он не меняется.
bp всегда использовал для алгоритма. Потому и написал что свободных регистров нет.
Тратить целый регистр на хранение указателя - это не по мне.

Вообще забавно вы ребятки спорите. Уверен, вот нифига вы не писали на асме тяжёлые алгоритмы
не старых машинах.

Добавлено через 13 минут
Цитата Сообщение от The trick Посмотреть сообщение
В чем проблемы?
В том что это не алгоритм и не отражает т.н. coding experience. В том что не проверено место в стеке,
в том что вы с Замабувараев вещаете это как единственно допустимую истину и говорите
что быстрее, где оно быстрее? Если я заведу память заранее. Где эта скорость себя окупит? На 386-м?
Почему при всех этих бенефитах не рассказано, как проверить стек и как изменить его размер.
А так же не рассказано, что стек будет заведён перманентно и будет занимать память не по необзходимости
а просто займёт сразу. В то время как программа которая написана с классическим резервированием
памяти из хепа будет высвобождать эту память, отдавая ресурс другим приложениям в системе
и не занимая его попусту.

Повторяю ещё раз это не аксиома для всех ЯП, на паскале и на бейсике нет этого функционала,
на некоторых диалектах только через вставки. Это прерогатива в большей степени низкого уровня.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
05.04.2021, 08:26  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
bp всегда использовал для алгоритма
А как вы тогда функции без пролога и эпилога создаёте? А адресацию к локальным переменным через rsp, что ли? Но ведь гораздо удобнее mov rbp, rsp и потом адресоваться от rbp.

Вот что выдаёт FreeBASIC на x64:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
; Начало функции
push    rbp
mov rbp, rsp
sub rsp, 64          ; резервирование под локальные переменные, замените на нужное количество байт
 
; делать очень полезную работу
 
; если нужно ещё памяти, то просто уменьшаем указатель стэка
; это всего одна инструкция процессора
sub rsp, 64         ; заменить на сколько надо
 
; конец функции
mov rsp,rbp         ; этой одной инструкцией освобождается вся локальная память функции
pop rbp
ret
Пролог и эпилог позволяет не обращать внимания на rsp, ведь он на любой чих может поменяться, и адресоваться по rbp, который не меняется.

Система выделяет целый мегабайт памяти на стэк, но это настраивается в параметрах компоновщика, так что все локальные переменные влезут.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 08:47
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Тратить целый регистр на хранение указателя - это не по мне.
Так ты предлагаешь выделять вместо этого громадный кусок памяти и в нем хранить данные, что менее рационально и намного более дорогостоящая операция чем сохранение регистра в стек.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
В том что это не алгоритм и не отражает т.н. coding experience.
Как не отражает? Я тебе могу кучу либ показать (написанных на ЯВУ) где такое выделение в стеке используется. Этим занимается компилятор.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
Если я заведу память заранее.
Ну и? Заведешь и что? Как это будет выглядеть? Кто будет следить за этой памятью? Вызываешь ты функцию что в этой памяти выделяет регион. Эта функция в свою очередь вызывает другую которая также выделяет память в этом региона. Как ты собираешься распределять эту память? Колхозить стек? Это ли не усложнение? У нас уже есть механизм для локальных переменных который реализован в железе и не не нужно что-то другое придумывать.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
А так же не рассказано, что стек будет заведён перманентно и будет занимать память не по необзходимости а просто займёт сразу.
Уже был спор у нас по поводу виртуальной памяти. Стек не занимает физической памяти пока это не нужно, есть область зарезервированного АП + закомиченого на момент запуска приложения (прописано в хидерах PE файла). И не нужно ничего от себя придумывать - выделение в хипе намного более сложная операция, т.к. основана на том же самом механизме. Второй очевидный минус хипа в том что память нужно освобождать что также несет накладные расходы. Для функций типа преобразования каких-нибудь идентификаторов в юникод и т.п. память выделенная в стеке - самый быстрый и эффективный вариант. По сути так и работает множество библиотек.
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
05.04.2021, 09:27
Цитата Сообщение от The trick Посмотреть сообщение
Зачем где-то заводить память (что намного дольше по времени), потом ее еще освобождать
Да, заводить и освобождать. Именно так. Подстраивать архитектуру под это. Стек не панацея,
если всё динамическое(а скорее всего в приличной проге так и будет) и там десятки
и сотни мегабайт крутятся, то какой нафиг стек.
Конечно локальные переменные хранятся в стеке, где им ещё храниться? И конечно есть
возможность хранить там в виде ByVal сами значения, но надо понимать чем это чревато,
с этим надо осторожно работать.
И речь даже не о вас, кто знает, а о тех людях, кто не особо знаком с этими проблемами, возьмут
и захотят гигабайт в стеке завести, потому что им сказали что оно быстрее, будут сидеть
чесать репу, мол что не так. Или начнут сравнивать, заведут там и там. Увидят одинаковую
скорость и не поймут почему быстрее, что бенефит в виде мелкозернистого резервирования памяти.
Чтобы этот бенефит прочувствовать нужен ещё и алгоритм соответствующий. А тут разговор
за строки идёт причём просто так, не применительно вообще к чему-то. Ну вот я и спросил
где такой софт, который тупо 100% времени ЦП работает со строками. И что этот софт
резервирует гигабайты стека? Где такое есть вообще?
И смысл тогда во всём этом? Если речь о ВУ, на большей части которого его даже и нет,
т.е. аппаратного процессорного стека, а не самопальной эмуляции простой структуры.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Адресация локальных переменных идёт через rbp
Могу адресацию к локальным делать и вообще без bp. Нет никаких правил там.
Правила все на ВУ. В машинных организуй как хочешь, на что мозгов хватает, там другие
критерии, все ресурсы отдаются под полный контроль программиста. Я туда например
вообще не лезу, пока меня всё устраивает на ВУ, вот когда перестаёт устраивать - тогда да.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Вот что выдаёт FreeBASIC на x64
Не пишу на x64. Только 16 и 32, так что мне этот код мало чего даёт. Не изучал, там свои
особенности и регистров больше. Так делал только тогда, когда было лень самому считать
смещения или цикл не давал это делать нормально. Хотя принципы экономии регистров всё те же.
А вот на 32 и 16 - это важно про что пишу. Потому как на элементарщину даже их не хватало.
Просто выводы не делаю на этих "сферах в вакууме". Попиши на асме алгоритмы с точки зрения
оптимизации, сразу поймёшь, про что говорю в этой теме. Причём попиши без помощи ВУ
именно сам руками организацию делай, раскидывай регистры по переменным и т.п., там просто
классическая вещь будет, листик слева код, справа все используемые регистры в тек момент.
Желательно это делать на старом компе, чтобы даже на глаз понимать где быстрее работает.
И нюансов там на самом деле много. Но один из нюансов уменьшать объём кода, кол-во команд,
а также зависимых команд. А ещё выравнивание, это не сложно само по себе, только с точки
зрения алгоритма, алгоритм потому что приходится дробить на несколько частей. Эффективный
код это вопрос тестирования больше. Есть у тебя штат 5-10 компов, со старых до новых - тогда
будет круто и хорошо. А просто какие-то идеологии муссировать - круто не будет.

Цитата Сообщение от Замабувараев Посмотреть сообщение
А как вы тогда функции без пролога и эпилога создаёте?
Компилятор сам этим занимается когда вставками делаю, просто доку надо смотреть
к каждому компилятору, что он там сохраняет, а что нет, по умолчанию если без док всегда считаю
что компилятор ничего не сохраняет и делаются минимальные pusha\popa. Бывает и не пишут
таких нюансов, или просто фиг найдёшь в справке.
Когда на чистом асме писал под DOS просто сохранял\восстанавливал все используемые регистры
руками и всё, никаких прологов этих Enter\Leave, в гробу я их видал. И сегменты все руками настраивал
включая стек. Но регистров лишних не было никогда, всегда все использовались по максималке.
Всё, что можно считать в регистрах лучше считать в регистрах.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Система выделяет целый мегабайт памяти на стэк, но это настраивается в параметрах компоновщика, так что все локальные переменные влезут.
Да выделить то не сложно, там директива есть у компилятора. Просто какая потребность для
обычной работы со строками, где-либо вывести строки, либо сохранить на диск. Первое обычно
синхронизировано по частоте развертки, второе просто делается медленнее в разы и тут это не
является тем фактором который может затормозить.
Вот серьёзно, зачем туда вообще лезть? И почему строки? А не какой-то специфический алгоритм.
Просто не вижу профита, такого, чтобы прям профит видимый на глаз. Ладно там даже 10%, вообще
мизерный профит, но профит, но эти копейки вычленять какие-то гипотетические. Мне вот это не
понятно, за что мы тут в реале пытаемся спорить.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
05.04.2021, 09:41  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Не пишу на x64. Только 16 и 32, так что мне этот код мало чего даёт.
На 32‐битах пролог и эпилог организуется аналогично, вместо регистра rbp будет ebp.
Доступ к локальным переменным идёт по положительному смещению: ebp[8], ebp[12], ebp[16] и тому подобное тагдалее.
Доступ к параметрам идёт по отрицательному смещению: ebp[-8], ebp[-12], ebp[-16] и прочее.
Всё просто же.
(для x64 первые четыре параметра передаются в регистрах, а потом в стэке)
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
05.04.2021, 09:47
Цитата Сообщение от The trick Посмотреть сообщение
Как не отражает?
Вот так не отражает. Я за себя пишу за свой код и надеюсь ты - за свой. Чужие либы мне не интересны
я в них ничерта не пойму, я 4 года не кодил серьёзно, чтобы лезть на чужой диалект, в чужие либы и чё-то
там пытаться найти ещё, это больше на троллинг меня похоже. Но уверен люди не дураки, там стопудово
ссаная мелочёвка, какие-то крупные и сложные алгоритмы за это дело не цепляют.

Цитата Сообщение от The trick Посмотреть сообщение
Я тебе могу кучу либ показать (написанных на ЯВУ) где такое выделение в стеке используется.
Лучше открой эти либы и посмотри зачем оно там используется в этих конкретных местах.

Цитата Сообщение от The trick Посмотреть сообщение
Для функций типа преобразования каких-нибудь идентификаторов в юникод и т.п. память выделенная в стеке - самый быстрый и эффективный вариант. По сути так и работает множество библиотек.
Цитата Сообщение от The trick Посмотреть сообщение
Уже был спор у нас по поводу виртуальной памяти. Стек не занимает физической памяти пока это не нужно
Если всё так радужно, то зачем же тогда нужны соотв. директивы компилятора для указания
того, сколько стека резервировать? Почему система тогда не резервирует стеку сразу объём
равный всей физической памяти?
Может быть вся эта система работает как говно? И начинает задирать жёсткие диски
И люди не хотят с ней связываться.

Добавлено через 2 минуты
Цитата Сообщение от Замабувараев Посмотреть сообщение
Всё просто же.
Я про это вкурсе. Там ещё есть конвенции о передаче параметров. Можно им не следовать.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 09:50
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Да, заводить и освобождать. Именно так. Подстраивать архитектуру под это. Стек не панацея,
если всё динамическое(а скорее всего в приличной проге так и будет) и там десятки
и сотни мегабайт крутятся, то какой нафиг стек.
Я тебе пишу о конкретных сценариях, а ты мне зачем-то пишешь про мегабайты динамической памяти. Не нужно. Я прекрасно знаю что большие объемы нельзя выделять в стеке. Почитай мое сообщение. Я пишу о том что используется в реальных задачах и говорю что в этих задачах стек более эффективен. Когда ты в C пишешь что-то типа char z[100], те же 100 байт в стеке выделяются. В С99 уже можно писать char z[a], т.е. выделить в стеке с динамическим размером и не использовать alloca.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
А тут разговор
за строки идёт причём просто так, не применительно вообще к чему-то. Ну вот я и спросил
где такой софт, который тупо 100% времени ЦП работает со строками. И что этот софт
резервирует гигабайты стека? Где такое есть вообще?
И смысл тогда во всём этом? Если речь о ВУ, на большей части которого его даже и нет,
т.е. аппаратного процессорного стека, а не самопальной эмуляции простой структуры.
Я тебя не пойму. То ты "удавишься" за лишний регистр в плане эффективности кода, то наоборот, предлагаешь вместо более эффективного кода использовать менее эффективный. В чем дело? Память в стеке - это лишь средство оптимизации. Зачем спорит с очевидным + выдумывать какие-то проблемы которых не существует?
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
05.04.2021, 10:07  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Там ещё есть конвенции о передаче параметров. Можно им не следовать.
Если им не следовать, то вы не сможете вызвать ни одну функцию, и не сможете использовать свои функции как функции обратного вызова.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 10:15
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Вот так не отражает. Я за себя пишу за свой код и надеюсь ты - за свой. Чужие либы мне не интересны
я в них ничерта не пойму, я 4 года не кодил серьёзно, чтобы лезть на чужой диалект, в чужие либы и чё-то
там пытаться найти ещё, это больше на троллинг меня похоже. Но уверен люди не дураки, там стопудово
ссаная мелочёвка, какие-то крупные и сложные алгоритмы за это дело не цепляют.
Я это пишу не просто так. Во-первых, я часто занимаюсь реверсом кода, и вижу как это работает уже в бинарях. Во-вторых, как я уже написал в C99 можно объявлять VLA которые в свою очередь выделяются в стеке:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
int main() {
 
    for (int i = 100; i < 1000; i += 100) {
        char b[i];
        int q[i * 2];
 
        b[i - 1] = 3;
        q[i] = 9;
 
    }
 
    return 0;
}
Вся память выделяется в стеке, массивы имеют изначально динамический размер.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
Лучше открой эти либы и посмотри зачем оно там используется в этих конкретных местах.
Я уже написал конкретный сценарий, и выложил конкретный дизассемблерный листинг. Этого недостаточно?

Цитата Сообщение от Quiet Snow Посмотреть сообщение
Если всё так радужно, то зачем же тогда нужны соотв. директивы компилятора для указания
того, сколько стека резервировать? Почему система тогда не резервирует стеку сразу объём
равный всей физической памяти?
Директивы нужны чтобы изменить значения по умолчанию. Прикладные приложения (в винде) вообще не работают с физической памятью, забудь про нее. Система могла бы только зарезервировать все виртуальное адресное пространство под стек, но она этого не сможет сделать т.к. помимо стека в АП содержится куча данных и при резервировании всей памяти не останется места для других данных.
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
05.04.2021, 10:37
Цитата Сообщение от The trick Посмотреть сообщение
предлагаешь вместо более эффективного кода использовать менее эффективный. В чем дело?
Дело в том про что пишу. Ты пишешь про автоматику, когда крутой компилятор даёт тебе доступ к стеку,
и вроде уже становится понятно, что об оптимальном коде речи нет, т.к. регистр просран.
Да компиляторы конечно уже как шахматные движки, но всё же, бывает и фигню морозят, например
об этом довольно давно писал автор VirtualDub.
Я же пишу про то что на бейсиках и паскалях и даже на твоём VB - этого функционала нет.
Этим тоже занимается компилятор, или можно заняться самому вставкой.
И в чём тогда вопрос, разрабы компиляторов что лохи сделать совсем дерьмовую систему?
Я вот кодил на PB, реально Turbo диалект, очень быстрый в задачах. FB тоже хватает настолько
чтобы до готовности почти любого софта забыть про ASM, редко что-то. И тут мне начинают втирать что
какие-то проблемы со строками, с памятью. Ну ёлы палы. Вот под DOS-ом были проблемы,
там вообще памяти не было, а сейчас всё зашибенно работает, кодерам вообще делать
считай ничего не надо, оптимизируется за них, памяти дофига, ну на 2-4 гига можно спокойно
рассчитывать, куча ядер у проца. И вот про что я пишу, про стек, на ассемблере, раз на этих
наших бейсиках он есть в виде вставок. Если у нас алгоритм, допустим даже, не знаю, простая
сортировка, там уже больше переменных чем регистров, сравниваем два значения значит нужно
иметь два индексных регистра два счётчика и два регистра общего назначения, двойной цикл -
плюс ещё регистр, и нужен стек, потому что внутри цикла идёт push/pop, по любому идёт, если
мы не используем глобалки. И если под DOS я понимал как их проще индексировать, скопировал
ds(там ещё было два халявных fs\gs) то тут как-бы бошкой приходится думать. И стек как бы важен
алгоритмически, в него быстрее пишется\читается(на старых ПК), не сильно но быстрее, нельзя
указатель двигать в цикле иначе будет жопа, это о том что нужны регистры и не везде можно
это сделать. А если сделал то будь добр подвинуть указатель назад, т.к. в стеке данные, которые
нужно вернуть соотв. кускам кода.
locm говорил про уровень ответственности, надо объяснять уровень ответственности при таком раскладе?
И это только старт, когда ещё ничего не взвешено, нет готового кода, нет 5-10 вариантов куда
переместить те или иные переменные по регистрам, чтобы сократить кол-во команд. И с каждой такой
веткой вариантов всё меньше и меньше. Вот что такое оптимизация.
Конечно я удавлюсь за лишний регистр, если я вообще решился полезть на асм. А иначе зачем лезть?
Написать на асме можно и хуже. Твой VB вон как лихо там лопатит под пенёк код, спаривает
инструкции, урабатывает более короткие по объёму кода варианты. FB так не умеет.

Добавлено через 17 минут
Цитата Сообщение от The trick Посмотреть сообщение
Во-вторых, как я уже написал в C99 можно объявлять VLA которые в свою очередь выделяются в стеке
Ну я рад за си, им то лофа, когда всё за них там делается да ещё и библиотек вагоны.
Мне то он что, у меня FB, весь код рукописный.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
05.04.2021, 10:41  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Я же пишу про то что на бейсиках
Как это нет во FreeBASIC? Ещё как есть: https://www.freebasic.net/wiki/KeyPgNaked

Модификатор Naked заставляет компилятор создавать процедуры без какого‐либо кода пролога/эпилога. Это полезно при написании небольших, быстрых функций с ассемблерными вставками без накладных расходов.

Пример:
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
' CDecl говорит, что параметры передаются через стэк в обратном порядке
Function subtract_c Naked CDecl( _
        ByVal a As Long, _          /' последний параметр '/
        ByVal b As Long _           /' первый параметр '/
    ) As Long
    
    Asm
        mov eax, dword Ptr [esp+4]  ' Теперь в регистре eax = a
        sub eax, dword Ptr [esp+8]  ' Вычитаем из eax параметр b
        ret                         ' return result in eax
    End Asm
    
End Function
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
05.04.2021, 11:05
Цитата Сообщение от The trick Посмотреть сообщение
Я уже написал конкретный сценарий, и выложил конкретный дизассемблерный листинг. Этого недостаточно?
То что ты писал это всё видел уже давно. Больше про другое писал, про сам процесс оптимизации.
Про то, что это не применимо везде и даже на си в плане оптимизации, когда алгоритм станет чуть сложнее
ровно настолько, чтобы все промежуточные переменные уже не лезли в регистры. Компилятор там конечно
начнёт изворачиваться всячески, циклы разворачивать, выравнивание данных делать, но это
всё немного не о том, о чём пишу. И например если не в функции, а просто в main-е. Вначале проги завести
эту самую стековую память и такие нормальные алгоритмы, которые забьют все регистры и по 3 вложенных
цикла делать, что там компилятор выдумает? Думаю ничего хорошего.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Модификатор Naked заставляет компилятор создавать процедуры без какого‐либо кода пролога/эпилога. Это полезно при написании небольших, быстрых функций с ассемблерными вставками без накладных расходов.
Видел этот модификатор. Там было ещё голое отправление в gcc. Пока не пользовался.
Вообще на асм под другим углом посмотрел, мне он теперь больше для логических штук и
битики отфильтровать и подвигать, вот это удобно.

Добавлено через 8 минут
Замабувараев ну а то, что ты отцитировал так Анатолий о другом писал. Он как раз не о вставке.
вставкой то понятно. Это больше мы спорим по НУ/ВУ. В FB нет функций как в си просто взять и
выделить память в стеке, да ещё и динамический объём. Или может психи разрабы уже добавили?
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 11:52
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Я же пишу про то что на бейсиках и паскалях и даже на твоём VB - этого функционала нет.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Option Explicit
 
Private Type tAutoVar
    bData(999) As Byte
End Type
 
Private Sub Main()
    Dim z As tAutoVar   ' // Выделяем в стеке 1000 байт
    
    z.bData(999) = 6
    
    Debug.Print VarPtr(z.bData(999)), VarPtr(z)
    
End Sub
Вот начало ассемблерного кода функции:

Assembler
1
2
3
4
5
6
7
CPU Disasm
Address           Hex dump          Command                                  Comments
00401930          /.  81EC E8030000 SUB ESP,3E8 ; 1000 байт
00401936          |.  56            PUSH ESI
00401937          |.  8B35 48104000 MOV ESI,DWORD PTR DS:[<&MSVBVM60.#644>]
0040193D          |.  57            PUSH EDI
0040193E          |.  33C0          XOR EAX,EAX
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Если у нас алгоритм, допустим даже, не знаю, простая
сортировка, там уже больше переменных чем регистров, сравниваем два значения значит нужно
иметь два индексных регистра два счётчика и два регистра общего назначения, двойной цикл -
плюс ещё регистр, и нужен стек, потому что внутри цикла идёт push/pop, по любому идёт, если
мы не используем глобалки. И если под DOS я понимал как их проще индексировать, скопировал
ds(там ещё было два халявных fs\gs) то тут как-бы бошкой приходится думать. И стек как бы важен
алгоритмически, в него быстрее пишется\читается(на старых ПК), не сильно но быстрее, нельзя
указатель двигать в цикле иначе будет жопа, это о том что нужны регистры и не везде можно
это сделать. А если сделал то будь добр подвинуть указатель назад, т.к. в стеке данные, которые
нужно вернуть соотв. кускам кода.
Ничего не будет, регистры можно также сохранять в стеке, адресуя к примеру через EBP.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
locm говорил про уровень ответственности, надо объяснять уровень ответственности при таком раскладе?
И это только старт, когда ещё ничего не взвешено, нет готового кода, нет 5-10 вариантов куда
переместить те или иные переменные по регистрам, чтобы сократить кол-во команд. И с каждой такой
веткой вариантов всё меньше и меньше. Вот что такое оптимизация.
Как раз код резервирующий место в стеке более оптимальный чем код выделяющий память в хипе. Когда можно использовать более быстрый подход со стеком вместо хипа - вот что такое оптимизация. Приведу аналогию. Я тебе говорю к примеру в некоторых задачах можно использовать линейный массив для данных если доступ к данным должен быть по индексу, ты мне говоришь, нет все фигня, нужно использовать ассоциативный массив для любых таких задач. Понимаешь?
0
 Аватар для CoderHuligan
1753 / 1018 / 257
Регистрация: 30.06.2015
Сообщений: 5,130
Записей в блоге: 56
05.04.2021, 12:02
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Если у нас алгоритм, допустим даже, не знаю, простая
сортировка, там уже больше переменных чем регистров, сравниваем два значения значит нужно
иметь два индексных регистра два счётчика и два регистра общего назначения, двойной цикл -
плюс ещё регистр, и нужен стек, потому что внутри цикла идёт push/pop, по любому идёт, если
мы не используем глобалки.
Есть еще вариант в виде static памяти. Даже в fb это реализовали на примере си. Статик будет глобал только для конкретной функции и не нужны затраты на стековые операции. Вообще чего мы экономим память? Машины стали мощнее, памяти завались.. Я бы попробовал сделать язык основанный на статик памяти без всякого стека. В этом случае вообще отпадает проблема порядка размещения параметров.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 12:08
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Ну я рад за си, им то лофа, когда всё за них там делается да ещё и библиотек вагоны.
Мне то он что, у меня FB, весь код рукописный.
Я написал про преимущества выделения памяти в стеке, ты же меня пытаешься в чем-то разубедить и оспорить мои высказывания, но так и не привел толком ничего чтобы опровергнуть мои слова. Тут даже к ЯП не нужно привязываться.
Вот твои высказывания:
>>Ничем. Эту тему я поднимал ещё ой как давно. Мужики по-моему над нами угарают.
>>Не знаю где люди этого набрались и почему нам выдают эти мимолётные вещи в виде понта за прописные истины.
>>И так понятно что это не ВУ и стандартом никогда не станет, что такой код это исключительно
>>рукописное асмовое, применимое строго местно и микроскопически.
ну и т.д. подобные заблуждения.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
Больше про другое писал, про сам процесс оптимизации.
Про то, что это не применимо везде и даже на си в плане оптимизации, когда алгоритм станет чуть сложнее
ровно настолько, чтобы все промежуточные переменные уже не лезли в регистры.
Я уже написал в каких случаях это применимо + уже сказал что нет такой проблемы с сохранением регистров в стек. Даже пример привел. Так и будешь повторять одно и тоже?

Цитата Сообщение от Quiet Snow Посмотреть сообщение
И например если не в функции, а просто в main-е. Вначале проги завести
эту самую стековую память и такие нормальные алгоритмы, которые забьют все регистры и по 3 вложенных
цикла делать, что там компилятор выдумает? Думаю ничего хорошего.
Ок. Грубо говоря у нас 10 переменных. В чем проблема регистры сохранять в стеке? Конкретно напиши, в чем проблема? Как делают подавляющее большинство компиляторов - заводят в стеке место под такие локальные данные и туда сохраняют переменные из регистров, если не хватает регистров. Все. Никаких проблем не возникает, хоть 100 переменных используй. С выделением массивов в стеке это вообще никак не связано. Массивы отдельно, локальные переменные отдельно. Все что ты написал - надуманная проблема.
0
Эксперт по электронике
6823 / 3248 / 337
Регистрация: 28.10.2011
Сообщений: 12,692
Записей в блоге: 7
05.04.2021, 12:38
Цитата Сообщение от The trick Посмотреть сообщение
Вся память выделяется в стеке, массивы имеют изначально динамический размер.
Не совсем так.
В Си переменные имеют область видимости в пределах блока. В этом коде размер массива не меняется. Он пересоздается.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 12:58
Цитата Сообщение от locm Посмотреть сообщение
Не совсем так.
В Си переменные имеют область видимости в пределах блока. В этом коде размер массива не меняется. Он пересоздается.
Все как я и написал. Размер массива имеют изначально динамический размер (в отличии от массивов со статическим размером где размер задается константой), я не писал что его можно изменить.
0
 Аватар для CoderHuligan
1753 / 1018 / 257
Регистрация: 30.06.2015
Сообщений: 5,130
Записей в блоге: 56
05.04.2021, 13:28
Крис Касперски писал, цитата, - "за размещение массивов в стеке давно пора расстреливать". Думаю, что он был прав, светлая ему память. Как то люди позабыли, что есть разные сегменты памяти, а не только сегмент стека. Есть глобальная секция data. И не нужно её бояться, так как она глобальна только для файла - единицы компиляции, чем обеспечивается модульность проекта. Особенно вредно в стеке размещать константные строки, так как они на стадии компиляции кладутся в секцию данных, а уже на стадии исполнения копируются в стек. А это ощутимые тормоза, причем совершенно бессмысленные. Для динамических строк есть куча. Стек же предназначен для хранения параметров и промежуточных(автоматических) переменных, ну и адресов возврата для функций. можно еще вспомнить хакерские атаки на стек, в которых массивы иногда выполняют функцию хранения шелл-кода. Короче говоря не надо пихать массивы в стек, это не кошерно.
0
Модератор
10057 / 3902 / 884
Регистрация: 22.02.2013
Сообщений: 5,853
Записей в блоге: 79
05.04.2021, 14:04
Цитата Сообщение от CoderHuligan Посмотреть сообщение
Стек же предназначен для хранения параметров и промежуточных(автоматических) переменных
Ну так локальные массивы к этому и относятся.

Цитата Сообщение от CoderHuligan Посмотреть сообщение
Есть глобальная секция data. И не нужно её бояться, так как она глобальна только для файла - единицы компиляции, чем обеспечивается модульность проекта.
И что? Как секция data поможет с локальными переменными функции (которые также могу быть массивами)?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.04.2021, 14:04
Помогаю со студенческими работами здесь

Стоит ли изучать как устроена ЭВМ для эффективного программирования
Всем дробового времени суток (пятница!!!) Стоит ли изучать как устроен ЭВМ для эффективного программирования на плюсах ?

Подскажите ссылки на приемы программирования для Embedded
Народ! Подскажите пожалуйста ссылки, на приемы и упражнения по программированию, с разьяснениями по встраеваемому ПО. Заранее благодарю!

Нужны сайты про C#, приемы, рецепты, трюки программирования
Не советуйте msdn или книгу. Справочник должен быть похож на другие стандартные справочники как у delphi, которых полно в инете, а к C#...

Интересны приемы программирования, о которых не пишут в книгах, а которые узнаются на практике
интересны приемы программирования на C# те о которых не пишут в книгах, которые узнаются на практике. какие OpenSource проекты можете...

Общие вопросы.
Доброго времени суток! После изучения Паскаля, решил перейти на изучение С/С++, прочитал много мануалов для новичков, но накопились...


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

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru