.386 ;шаблон структуры Node struc namex db 4 dup(0ffh) field1 dw 2 dup (0) Node ENDS ;логический сегмент Data1 segment use16 I_struc db ? A0 Node <> A1 Node 2 dup (<>) A2 Node 4 dup (<>) A3 Node 8 dup (<>) adress dw begin2, code2 Data1 ends 

It is necessary to create a tree, where in the 2-element array of field field1 of structure A0, the offset in the segment of 2 structures from the array of structures A1 is written. In the 2-element array of the field field1 of the structure A1 [0], we shift the offset in the segment of the structures A2 [0] and A2 [1], etc. When writing a program to index arrays of structures, use byte by address I_struc.

 code1 segment use16 assume cs:code1, es:Data1 begin: mov ax, Data1 mov es, ax mov si, 0; mov di, 0 mov bx, 0 lea bx, A2[0] Loop_Begin: mov A0[di].field1[0],bx add bx, type A2 mov A0[di].field1[2],bx jle Loop_Begin 
  • And the question is what is it? And filed1 [2] can not be, we have two elements from scratch: 0 and 1, at number 2 this is the third element. - Mike
  • The question is that I simply do not understand how to do this task, and yes, you are absolutely right about filed1 [2], thank you. - Sasha Urban
  • I think I would make a function that takes 3 parameters (say in si, di, cx): a pointer to the upper array, a pointer to the next one and the number of elements in the upper one. the function in the loop fills the field of the Nth element in the first array with offsets N * 2 and N * 2 + 1 elements of the second array. After which he would have called her 3 times A0, A1.1; A1, A2.2; A2; A3,4 - Mike
  • True point-blank I do not understand the condition of the problem about l_struc. - Mike
  • I think it will be enough to create 3 cycles, but on the condition about l_struc, I think you can "forget it" - Sasha Urban

1 answer 1

I can not understand the condition "When writing a program to index arrays of structures, use byte by address I_struc". The x86 addressing system does not allow single-byte memory operands to address something. And to overload a byte from memory to the register, increase by 1 and save back into memory and all in order to multiply it later by the size of the structure and get to the array element through it, this is an obvious search. To go to the next element it is much easier to simply shift the pointer in the register to the size of the structure.

Here, from my point of view, the optimal algorithm for filling such a tree. All memory operations and the use of constants inside loops are minimized.

  mov ax, Data1 mov ds, ax push offset A3 ; Сохраняем адреса уровеней дерева на будущее, в обратном порядке (т.к. стек) push offset A2 push offset A1 mov ax, type Node ; AX - размер структуры, для быстрого использования mov dh, 1 ; DH - количество элементов на текущем уровне дерева mov di, offset A0 ; DI - Адрес второго уровня дерева, в начале цикла он станет первым уровнем (SI) mov cx, 3 ; CX - Количество оставшихся уровней дерева LevelUP: ; Начало цикла по уровням дерева mov si, di ; SI - Указатель на текущий элемент первого уровня (прошлый второй уровень) pop di ; Загружаем из стека новый адрес второго уровня mov bx, di ; BX - смещение текущего элемента второго уровня mov dl, dh ; DL - оставшееся количество не обработанных элементов в первого уровня NextNode: ; Цикл по элементам первого уровня mov [si].Node.field1[0], bx add bx, ax ; Смещаем указатель на следующий элемент второго уровня mov [si].Node.field1[1], bx add bx, ax add si, ax ; Смещаем указатель на следующий элемент первого уровня dec dl jnz NextNode shl dh, 1 ; На следующем уровне в 2 раза больше элементов loop LevelUP 
  • Thanks, very helpful. And forgive me for not giving thanks for a long time, shook. - Sasha Urban
  • Understood, thanks again :) - Sasha Urban