2010-11-04 2 views
3

Как распределить память в сборке при использовании нескольких массивов. Например, у меня есть 2 массива;Сборка памяти с несколькими массивами памяти

la $s0, X 
la $s1, Y 

если «инициализировать» это таким образом, распределение памяти является непрерывным, например

Address  +0  +4  +8  +12  ..... 
22112  x[0]  y[0]  x[1]  y[1] ... 
. 
. 
. 

Для того, чтобы «исправить», что, я думал о загрузке адреса кулака массива инициализации n значения а затем оттуда инициализировать другое. Например

arrayAllocationX: 
    la $t0, X 
    fill with $zero until n-1($t0) 
    la $s0, X 

arrayAllocationY: 
    la $t1, Y 
     fill with $zero until n-1($t1) 
    la $s1, Y 

Это не работает, как это, заявляя la $s0, X и la $s1, Y продолжает сохранять значения смежно.

Я, хотя, другие способы сделать это, что может работать, например; Заполнение элементов смежно и при чтении значения для адреса памяти массива 1, поэтому x [0] = Адрес 2234 -> x [1] = 2234 + 8. Но это не похоже на хорошую практику программирования.

Можете ли вы посоветовать мне, на каком правильном пути, сделать это. Благодаря!


Кстати, ценности всегда вводятся, и читать в последовательности (первый х, то у)

ответ

2

Я надеюсь, что я не искажая ваш вопрос, но выделение памяти для массива обычно делается специальная ассемблерная директива, а не отдельные инструкции. К сожалению, синтаксис меняется, но общая идея заключается в том, чтобы попросить ассемблера выделить некоторое пространство. Предположим, что массив X нуждается в 100 Интс и массив Y 200. Вот как некоторые монтажники делают это:

X: defs 100*4 
Y: defs 200*4 

Другие могли бы сказать: «.byte» вместо „DEFS“. «* 4» - это то, что вы выделяете пространство в байтах, но каждый int составляет 4 байта. Иногда у сборщиков есть способ сказать «выделить пространство и заполнить его некоторым значением». То, что я здесь изложил, не будет делать этого, чтобы быть уверенным, что вам нужно теперь написать начальные значения. Давайте заполним X с 1-х и Y с 2-х:

 la $t0,X   ; get address of X array into $t0 
    mov $t1,100  ; number of items in X into $t1 
    mov $s0,1   ; All X[] to be filled with 1 
xlp: st $s0,0($t0) ; write next X[] value 
    add $t0,$t0,4  ; move to next position in X[] array 
    add $t1,$t1,-1 ; count down one less item 
    bne $t1,0,xlp  ; keep doing this until we get to zero 

    la $t0,Y 
    mov $t1,200 
    mov $s0,2 
ylp: st $s0,0($t0) 
    add $t0,$t0,4 
    add $t1,$t1,-1 
    bne $t1,0,ylp 

Комментариев являются своим родом излишними, но я хотел бы вновь повторять то, что я делаю в вероятном случае, если я забыл свой MIPS ассемблерных мнемоник или сделал ошибка.

Динамическое распределение массивов - это совсем другое предложение. Обычно будет подпрограмма операционной системы, которую вы вызываете, чтобы получить указатель на кусок памяти определенного размера. Если вы действительно на низком уровне, вам придется придумать свою собственную схему. Как ни странно, это само собой заключается в объявлении статического массива, который охватывает всю доступную память, а затем передает ее куски, как это просит программа. Тогда вам нужно успеть следить за тем, что вы передали, чтобы вы могли освободить куски.

В любом случае вам будет предоставлен указатель на объем запрашиваемой памяти. Обычно вам нужно сохранить этот указатель в ячейке памяти, но он может жить в регистре для простой программы. Код распределения может выглядеть примерно так:

X:  word 0 

mov $t0,100*8 ; how much memory we will need 
bal alloc  ; get memory -- assume it returns pointer in $t1 
la  $s0,X  ; X pointer address 
st  $t1,0($s0) ; keep track of start of array 

Обратите внимание, что нам нужно сделать два шага, чтобы получить адрес массива. До того, как «X» был адресом используемой памяти. Теперь «X» - это адрес 4 байта памяти, который содержит адрес массива.

Предыдущий код инициализации будет работать, как и раньше, но вместо простого «ла $ t0, X» вам придется:

la $t0,X 
l $t0,0($t0) 

Если вы знакомы с C, разница здесь так же, как «int X [100];» vs. "int * X = malloc (100 * sizeof (int));". В обоих случаях вы можете сказать «X [n]», но за кулисами C использует правильные ассемблерные последовательности.

+0

отличный ответ george и спасибо за то, что вы так подробно. Однако моя проблема возникает, когда мне нужно вводить элементы в оба массива одновременно. Например, ваше имя в x [0] и ваш телефон в y [0]. Кроме того, я думаю, не может использовать «defs/.space», потому что размер массива неизвестен до исполнения. Было бы плохой практикой, как я сказал: «Заполнение элементов смежно и при чтении значения для адреса памяти массива 1. X [0] = Адрес 2234 -> y [0] = 2234 + 4"? – Carlos

+0

Имена усложняют вещи, потому что они имеют тенденцию к переменной ширине. Но то, что вы предлагаете, отлично подходит для значений фиксированного размера. Это больше всего один массив с двумя связанными частями данных в каждой позиции. В терминах C - массив структур. Если регистр $ t0 указывает на элемент в массиве, «l $ s0,0 ($ t0)» может получить зарплату и «l $ s0,4 ($ t0)» возраст. Переход к следующему элементу массива означает добавление 8 к $ t0. Динамическое распределение памяти - это совсем другое. Я уточню свой ответ. –

+0

УДИВИТЕЛЬНЫЙ ОТВЕТ !!!! Спасибо, Джордж! – Carlos

Смежные вопросы