The Bird of Hermes
А я хочу чтобы можно было вычислить размер массива только по его смещению где бы он ни был
The Bird of Hermes
сам понял что сказал?
При условии что после хоть что-то идёт это должно быть возможно
Aiwan \ (•◡•) / _bot
А я хочу чтобы можно было вычислить размер массива только по его смещению где бы он ни был
это ка квычислить рост человека зная его абсолютную отметку относительно моря
Aiwan \ (•◡•) / _bot
При условии что после хоть что-то идёт это должно быть возможно
ну делай метку конца массива и высиляй размер
The Bird of Hermes
это ка квычислить рост человека зная его абсолютную отметку относительно моря
На голове у этого человека есть шляпа, относительное положение которой мы тоже знаем, только мы не знаем, какой именно шляпы
The Bird of Hermes
пример давай реальный.
Допустим, есть такая структура: arr db 5 dup (8) arr_end db 0 Я передаю в функцию смещение массива. Я не знаю смещение переменной после него, но я знаю, что эта переменная точно есть. Если ты говоришь, что существует некоторая таблица, которая по номерам содержит смещение каждой метки, то мне надо просто найти в этой таблице метку, следующую сразу за моим массивом
Aiwan \ (•◡•) / _bot
если это массив, то также известен его размер.
Aiwan \ (•◡•) / _bot
и смещение переменной за массивом будет сумма адреса массива и его размера в байтах
The Bird of Hermes
The Bird of Hermes
☝️
Погоди, но для этого мне надо знать смещение того, что идёт сразу после массива
Aiwan \ (•◡•) / _bot
Погоди, но для этого мне надо знать смещение того, что идёт сразу после массива
это символ $, если его использовать в выражении определения размера. или ставить метку конца массива и вычислять через разность меток конца и начала
Aiwan \ (•◡•) / _bot
arr db 5 dup (8) arr.size = $ - arr или arr db 5 dup (8) arr.end: arr.size = arr.end - arr
The Bird of Hermes
arr db 5 dup (8) arr.size = $ - arr или arr db 5 dup (8) arr.end: arr.size = arr.end - arr
Я хочу чтобы я мог определять длину массива как раз без всех этих дополнительных телодвижениц
The Bird of Hermes
Это должно быть возможно путём доступа к той самой таблице адресов
Aiwan \ (•◡•) / _bot
Я хочу чтобы я мог определять длину массива как раз без всех этих дополнительных телодвижениц
так это асм все делает за тебя. ну если хочешь сам, то передавай в функции также и метку конца массива и вычисляй размер массива сам
The Bird of Hermes
ее надо создавать вручную
Ну допустим я знаю что метка есть, но не знаю какая конкретно это метка
Aiwan \ (•◡•) / _bot
Ну допустим я знаю что метка есть, но не знаю какая конкретно это метка
давай пример. как ты не можешь знать что за метка, если код пишешь ты?
The Bird of Hermes
давай пример. как ты не можешь знать что за метка, если код пишешь ты?
Это допущение, я просто хочу уменьшить количество входных данных для определения длины массива. Чтобы в функцию можно было, допустим, передавать только смещение самого массива, а не его размер тоже
Aiwan \ (•◡•) / _bot
не передавай, а считай тогда при компиляции программы
The Bird of Hermes
не передавай, а считай тогда при компиляции программы
Так, ладно. Можно как-то напрямую получить доступ к таблице адресов или нет? Без указания адреса конкретного элемента, а к области памяти, где они хранятся?
The Bird of Hermes
конечно. создай такую таблицу и пользуйся
Ну так ты же сказал, что она где-то уже есть
The Bird of Hermes
И оттуда сам ассемблер берёт данные
Aiwan \ (•◡•) / _bot
Aiwan \ (•◡•) / _bot
А откуда он его берёт?
это было объяснение на этот вопрос
Aiwan \ (•◡•) / _bot
И оттуда сам ассемблер берёт данные
не берет, а считает во время компиляции
The Bird of Hermes
не берет, а считает во время компиляции
Но lea ведь работает не только во время компиляции
The Bird of Hermes
Но и при выполнении программы тоже
Aiwan \ (•◡•) / _bot
причем тут lea. это вообще из другой оперы
The Bird of Hermes
Ну она тоже считает адрес же
Aiwan \ (•◡•) / _bot
Ну она тоже считает адрес же
да, если продолжать тему кто/что может считать адрес, то туда еще mov можно приплести
The Bird of Hermes
Aiwan \ (•◡•) / _bot
Ну вот, как они его считают. При компиляции ладно, а они?
считают то что написано в операнде, посредством ALU процессора (это про lea)
disba1ancer
А откуда он его берёт?
вычисляет, либо на месте, либо на это делает линкер
disba1ancer
Но и при выполнении программы тоже
она работает так: берётся адрес метки и кладётся в регистр, по сути как mov который кладёт константу в регистр, но с дополнительными плюшками, если в качестве аргумента для lea (в т.ч. через offset для mov с константой) используется метка, то при ассемблировании вычисляется адрес этой метки и подставляется в команду, если вычислить адрес не представляется возможным, то просто заполняется нулями и на более поздних этапах заменяется адресом метки, в итоге прямо в инструкции, в секции кода, у тебя будет непосредственно адрес метки
Eugene
Нет никакой таблицы адресов меток. Это таблица есть только у компилятора (пока он разбирает твой код). В самой проге или в системе никаких таких таблиц нет. Там вообще нет никакой инфы о метках. Метки нужны лишь для удобства указания места какого-либо кода или данных, чтобы как-то указать в коде к какому именно месту мы обращаемся. org 400000h mov eax,[var] var dd 1000 Здесь var - это просто символьное обозначение адреса 400005h. Никуда дополнительно этот адрес в бинарь не записывается. Он пишется только в mov как mov eax,[400005h]. Всё. И адрес следующей метки ты никак не получишь. Ты можешь разве что сделать это через макросы. Скажем, опередить макрос типа: macro dstr label*, string*& { label db string label#.len = $ - label } (точно не помню как конкатенация имён делается в fasm, но вроде так). И далее, когда ты передаёшь в другой макрос метку, например, mystr (созданную макросом dstr), то этот макрос может добавить в концу .len и получить размер строки. Но опять же, это всё только в макросах. Макросы имеют доступ к символам твоего кода, а бинарный код - нет.
The Bird of Hermes
Хм, ясно
The Bird of Hermes
Тогда другой вопрос. Как выделять память в процессе выполнения программы?
The Bird of Hermes
Допустим, если я хочу реализовать список
The Bird of Hermes
Нет никакой таблицы адресов меток. Это таблица есть только у компилятора (пока он разбирает твой код). В самой проге или в системе никаких таких таблиц нет. Там вообще нет никакой инфы о метках. Метки нужны лишь для удобства указания места какого-либо кода или данных, чтобы как-то указать в коде к какому именно месту мы обращаемся. org 400000h mov eax,[var] var dd 1000 Здесь var - это просто символьное обозначение адреса 400005h. Никуда дополнительно этот адрес в бинарь не записывается. Он пишется только в mov как mov eax,[400005h]. Всё. И адрес следующей метки ты никак не получишь. Ты можешь разве что сделать это через макросы. Скажем, опередить макрос типа: macro dstr label*, string*& { label db string label#.len = $ - label } (точно не помню как конкатенация имён делается в fasm, но вроде так). И далее, когда ты передаёшь в другой макрос метку, например, mystr (созданную макросом dstr), то этот макрос может добавить в концу .len и получить размер строки. Но опять же, это всё только в макросах. Макросы имеют доступ к символам твоего кода, а бинарный код - нет.
У меня не fasm, а tasm
Eugene
Тогда другой вопрос. Как выделять память в процессе выполнения программы?
ОС какая? Либо вручную: просто резервируешь в секции .data? максимальный блок через array db 50000 dup (?) и дальше манипулируешь этим участком памяти. Либо HeapAlloc и т.п., если винда. Под ДОС тоже есть функции: ah=48h,49h,4Ah - на память пишу, что-то около того.
Eugene
Но учти, что если работать через функции ОС, то расход памяти будет больше (особенно, если нужно выделять мелкие кусочки: по несколько байт).
Eugene
В программах .COM вся память выделена программе изначально (хотя в .EXE вроде тоже, если не укажешь при компиляции иное), поэтому сначала её нужно ужать :) Это если про функции ДОС.
The Bird of Hermes
А сегмент кода и сегмент данных не изолированы друг от друга?
Aiwan \ (•◡•) / _bot
Eugene
А сегмент кода и сегмент данных не изолированы друг от друга?
Что значит изолированы? Они не пересекаются. Но никакой защиты доступа в ДОС нет.
The Bird of Hermes
смотря что считать изолицией
Если в в сегмент данных после объявленных переменных буду пихать что-нибудь, я ничего не сломаю?
Aiwan \ (•◡•) / _bot
нет
Aiwan \ (•◡•) / _bot
можешь асмокод туда запихнуть, он будет считаться/ассемблироваться как набор байт. но с тасмом в этом не уверен
The Bird of Hermes
можешь асмокод туда запихнуть, он будет считаться/ассемблироваться как набор байт. но с тасмом в этом не уверен
Я как раз не хочу чтобы он ассемблировался, а использовать как временный буфер или вовсе как постоянное хранилище для данных
Eugene
Я как раз не хочу чтобы он ассемблировался, а использовать как временный буфер или вовсе как постоянное хранилище для данных
Процессору всё равно - код это или данные. Он может читать/писать код и исполнять данные, если надо. Главное за пределы не выходи без понимания последствий.
The Bird of Hermes
Или не затру ли я уже имеющийся код
Eugene
Сегменты кода и данных не пересекаются.
Eugene
Выдели объявлением через dup столько места, сколько тебе нужно. Если это неинициализированные данные.
Eugene
И ничего не затрёшь.
The Bird of Hermes
The Bird of Hermes
В том прикол, что я могу заранее не знать, сколько памяти мне потребуется при исполнении. Поэтому и хочу себе динамическое её выделение
Aiwan \ (•◡•) / _bot
(тут случай когда проще написать прогу самому, чем объяснять элементарные вещи из учебников)
Eugene
А про выделение я уже писал выше.
Eugene
Даже екзешники этим ограничены?
Базовые регистры эти ограничены (не Е).