MASM32 Расположение памяти - PullRequest
       11

MASM32 Расположение памяти

1 голос
/ 15 февраля 2009

Я пытаюсь прочитать из основной памяти, используя сборку masm32, и для этого я создал (как ранее было рекомендовано в ответе на другой из моих вопросов здесь) массив, который будет содержать сильно разделенные области памяти (чтобы избегать чтения из кеша). Мне удалось создать массив и прочитать его, однако у меня есть проблема. Этот массив, который я уже сделал и протестировал, работает с данными, которые я ему дал (т.е. числами), и все работает. Но мне нужны места в памяти, и я нигде не могу найти карту или ссылки на них. Я имею в виду, мне нужно что-то вроде:

my_arr db 5, 2, 8, 9, 1, 7, 3, 0, 4, 6

но вместо использования цифр я должен использовать зарезервированные слова в соответствующей ячейке памяти. Но я не могу их найти = (или даже не знаю, что еще искать.


Редактировать

Позвольте мне просто проверить, правильно ли я понял, тогда вы скажете, что я могу (вместо использования массива использовать переменные со всем пробелом между ними для принудительного чтения из основной памяти, верно?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2009

Косвенный доступ к памяти в сборке

Чтобы рассматривать байты в массиве как адреса памяти, вам необходимо загрузить их в регистр, который может служить базовым адресом, а затем получить доступ к памяти, указанной регистром:

MOV AX, [MY_ARR+3]  ; Element 3 in array, that is 9
MOV BX, [AX]        ; Read from that address

О кешах

Обратите внимание, что ваш кэш, вероятно, намного больше, чем диапазон адресов памяти, охватываемых этим массивом, поэтому все будет помещаться в кэш.

Кроме того, учтите, что ваш кеш, вероятно, является ассоциативным, а это означает, что адреса, расположенные очень далеко друг от друга, могут помещаться вместе в кеш, если они не находятся в одинаковых (полных) строках кэша.

Чтобы фактически запустить кеш и гарантировать, что вам придется обращаться к памяти напрямую, вы должны получить доступ (в цикле) к ряду последовательных областей памяти, больших, чем ваш кеш. То есть создать массив размером с ваш кеш. Также примите во внимание, что, возможно, существует несколько уровней кэша (L1, L2, возможно, L3 и далее), поэтому насколько большим вам должно быть, зависит от того, какой кэш вы хотите переполнить.


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

Моя программа, однако, была не самым эффективным способом сделать это, а также не особо намекала на ассоциативность кэша (мне пришлось бы измерять это отдельно, зная схему раскраски). Тем не менее, оба были сделаны довольно эффективно относительно независимым от архитектуры способом с несколькими продуманными уловками в работе SIGMETRICS 2005 Ларри Маквой и Карлом Стейлином .

0 голосов
/ 15 февраля 2009

Это массив (смежных) байтов, как вы сказали:

my_arr db 5, 2, 8, 9, 1, 7, 3, 0, 4, 6

Это переменная, которая занимает 10 МБ (что больше по сравнению с кэшем ЦП):

wasted_space BYTE 10485760 DUP(?)

Вот несколько переменных с большим количеством потерянного пространства между ними:

my_var_1 db 5
spacer_1 BYTE 10485760 DUP(?)
my_var_2 db 2
spacer_2 BYTE 10485760 DUP(?)
my_var_3 db 8
spacer_3 BYTE 10485760 DUP(?)
my_var_4 db 9
spacer_4 BYTE 10485760 DUP(?)
my_var_5 db 1
spacer_5 BYTE 10485760 DUP(?)
my_var_6 db 7
spacer_6 BYTE 10485760 DUP(?)
my_var_7 db 3
spacer_7 BYTE 10485760 DUP(?)
my_var_8 db 0
spacer_8 BYTE 10485760 DUP(?)
my_var_9 db 4
spacer_8 BYTE 10485760 DUP(?)
my_var_10 db 6

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

Еще один способ получения адресов памяти - это вызов API O / S, которые выделяют память из кучи и возвращают адрес этой выделенной памяти, например, возможно, API HeapAlloc или VirtualAlloc.


Я не знаю, почему вы делаете это в ASM (за исключением изучения ассемблера). Если бы вы узнали о кешировании, я бы подумал, что вы могли бы сделать это точно так же (и более легко), используя C.

Во всяком случае, мне стало любопытно, что кеширование: сколько места достаточно, чтобы вызвать пропадание кеша? Сколько разных переменных необходимо, чтобы начать вызывать пропуски (учитывая, что кеш разделен и поэтому может содержать несколько (но только несколько) широко разнесенных кешей памяти)?

Это (кеширование) с годами стало сложным предметом, по-видимому. http://lwn.net/Articles/252125/ - статья из Википедии. Эта статья включает в себя некоторые графики, например, Рисунок 3.11: Последовательное чтение для нескольких размеров .

...