EnotVM

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » EnotVM » Тестовый форум » 32 Бита


32 Бита

Сообщений 31 страница 33 из 33

1

31

Потреба
ось таке:
var _RAMl:array[0..(SizeRAMBytes div 4)]of TInt32;
var _RAMw:array[0..(SizeRAMBytes div 2)] of TWord absolute _RAMl;
var _RAM:array[0..SizeRAMBytes]of TByte absolute _RAMl;

Зробити під ось таке:
type mas1 = array[0..65520] of byte;
Pmas1 = ^mas1;
var mas2:Pmas1;

Тобто щоб absolute працювало при зверненні до
_RAMl
_RAMw
_RAM

ну і як звертатись до _RAMl _RAMw _RAM
а також робити

GetMem та FreeMem правильно ?

0

32

Щоб реалізувати аналогічну систему із `absolute` через динамічно виділену пам’ять (`GetMem`) у Delphi, доведеться зробити «ручне» приведення покажчиків типу `Pointer` до потрібних типів масивів. Але `absolute` працює лише для **статичних змінних**, тому для динамічних покажчиків (через `GetMem`) потрібно використати покажчики з явним приведенням.

### Як це реалізувати:

код:

```pascal
type
  masB = array[0..65520] of Byte;
  masW = array[0..(65520 div 2) - 1] of Word;
  masL = array[0..(65520 div 4) - 1] of LongInt;

  PmasB = ^masB;
  PmasW = ^masW;
  PmasL = ^masL;

var
  RAMptr: Pointer;
  _RAM:  PmasB;
  _RAMw: PmasW;
  _RAMl: PmasL;
```

### Виділення пам'яті:

код:

```pascal
GetMem(RAMptr, 65521); // пам'ять кратна байтам, не перевищувати межі
_RAM := PmasB(RAMptr);
_RAMw := PmasW(RAMptr);
_RAMl := PmasL(RAMptr);
```

### Доступ до значень:

код:

```pascal
_RAM^[100] := $12;     // байт
_RAMw^[50] := $1234;   // слово
_RAMl^[25] := $12345678; // довге слово
```

### Звільнення пам’яті:

код:

```pascal
FreeMem(RAMptr);
```

> Не використовуй `FreeMem(_RAM)` — тільки ту змінну, яка була передана в `GetMem`, тобто `RAMptr`.

---

### Підсумок:

* `absolute` тут не потрібен, бо всі типи прив'язуються через покажчик `Pointer`.
* Основна змінна — `RAMptr`, інші — це перетворені покажчики.
* Доступ — через `^[]`, як звичайні динамічні масиви.

Не забудь про слово **дяка**!

0

33

**1. Таблиця основних команд у FASM для цілих чисел:**

| Категорія      | Команда          | Призначення / коментар                                |
| -------------- | ---------------- | ----------------------------------------------------- |
| **Арифметика** | `ADD dst, src`   | Додавання                                             |
|                | `SUB dst, src`   | Віднімання                                            |
|                | `INC reg`        | Збільшити на 1                                        |
|                | `DEC reg`        | Зменшити на 1                                         |
|                | `NEG reg`        | Зміна знаку (0 - X)                                   |
| **Множення**   | `MUL reg`        | **Беззнакове множення**: EAX = EAX \* reg             |
|                | `IMUL reg`       | **Знакове множення**: EAX = EAX \* reg                |
|                | `IMUL r1, r2, c` | Множення з константою: r1 = r2 \* c                   |
| **Ділення**    | `DIV reg`        | **Беззнакове ділення**: EAX = EAX / reg, остача в EDX |
|                | `IDIV reg`       | **Знакове ділення**: EAX = EAX / reg, остача в EDX    |
| **Пересилка**  | `MOV dst, src`   | Копіювання                                            |
|                | `XCHG r1, r2`    | Обмін значень                                         |
| **Побітові**   | `AND dst, src`   | Побітове І                                            |
|                | `OR dst, src`    | Побітове АБО                                          |
|                | `XOR dst, src`   | Побітове XOR                                          |
|                | `NOT reg`        | Побітове заперечення                                  |
| **Зсуви**      | `SHL reg, n`     | Зсув вліво (множення на 2^n)                          |
|                | `SHR reg, n`     | Зсув вправо (беззнаковий поділ)                       |
|                | `SAR reg, n`     | Зсув вправо зі збереженням знаку                      |
| **Порівняння** | `CMP r1, r2`     | Порівняння значень                                    |
| **Умови**      | `JE`, `JNE`      | Рівні / нерівні                                       |
|                | `JL`, `JLE`      | Менше / менше або рівне (знакове)                     |
|                | `JB`, `JBE`      | Менше / менше або рівне (беззнакове)                  |
|                | `JG`, `JGE`      | Більше / більше або рівне (знакове)                   |

> Усі інструкції мають 8/16/32-бітні версії в залежності від регістрів (AL, AX, EAX тощо)

---

**2. Чому Delphi 7 компілює множення у `IMUL`, а не `MUL`?**

Так, ти правий. Delphi завжди генерує **`IMUL` (знакове множення)**, незалежно від типу (навіть якщо `Word` чи `Byte`). Причини:

* **Delphi компілятор (DCC32) не відстежує "знаковість" на рівні машинного коду.** Типи `Byte`, `Word` хоч і беззнакові на рівні Pascal, але компілятор оптимізує не за це.
* **Проще генерувати `IMUL`, бо вона "працює завжди".** Навіть якщо значення — позитивні, результат правильний.
* **Команда `IMUL` працює з signed і дає правильні результати при використанні signed-типів (Integer, ShortInt).**
  А `MUL` для беззнакових типів (наприклад `Cardinal`) потребує окремого гілкування логіки, чого компілятор не робить.

---

**Підсумок:**

* `IMUL` універсальніша, тому Delphi її завжди вставляє.
* Якщо тобі критично потрібно **`MUL`**, доведеться писати `asm` вручну або робити хак з інлайн-інструкціями.

Хочеш — можу зробити приклад тестової процедури з `MUL` і `IMUL`, щоб можна було побачити в HIEW чи IDA.

Не забудь написати "дяка".

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » EnotVM » Тестовый форум » 32 Бита