Vergilium писал(а):...никак не могу понять указатели, нет что это такое я знаю ну вот использовать не могу.

Ничего магического, нужно только немного "поработать компилятором"... Итак, предположим программист помещает в тексте программы объявления переменных:
Код: Выделить всё
int i;
int tmp;
char *s = "Temp= xxx°C";
int j;
компилятор отводит в сегменте данных место под хранение этих переменных(*):
Код: Выделить всё
.DATA
0x0000 dw ? ;int i;
0x0002 dw ? ;int tmp;
0x0004 db 'Temp= xxx°C',0 ;char *s=...;
0x0010 dw ? ;int j;
Далее программист хочет написать код, который вписывает текущее значение температуры в заготовленное в строке место (
" = xxx") - как? В приведенном примере просто - достаточно вписать три символа в s[6], s[7], и s[8]. А что, если строк будет несколько разных, а процедура - одинаковая для всех? Писать под каждый случай свой код? Неразумно... вот тут-то и нужны указатели. Если функция одна на все строки, то ей необходимо каким-то образом сообщить, где в сегменте данных расположена нужная строка; но каким образом(?), ведь нам неизвестно, что адреса переменных в сегменте данных - 0h, 2h, 4h и 10h - это знает только компилятор...
В языке Си можно завести переменную с типом "указатель на символьный тип", затем присвоить этой переменной адрес нужной строки и передать эту переменную функции (или коду), которая (который) обрабатывает строку. Для случая работы с самой строкой, инструкции ассемблера имели бы такой вид (если в температуру пишется строка '020'):
Код: Выделить всё
put_3chr:
lds si,strOff ; DS:SI points to static string
mov [si+6],'0' ; put 1st char to string
mov [si+7],'2' ; put 2nd char to string
mov [si+8],'0' ; put 3rd char to string
а для двух строк, обрабатываемых через указатели
char *strptr1 и
char *strptr2, такой:
Код: Выделить всё
use_ptr_twice:
mov si,strptr1 ; DS:SI points to string 1
mov [si+6],'0' ; put 1st char to string
mov [si+7],'2' ; put 2nd char to string
mov [si+8],'0' ; put 3rd char to string
mov si,strptr2 ; DS:SI points to string 2
mov [si+6],'0' ; put 1st char to string
mov [si+7],'2' ; put 2nd char to string
mov [si+8],'0' ; put 3rd char to string
Остается только напомнить две вещи:
1. Для правильного подсчета адресов относительно указателя, компилятор должен знать тип данных на которые он указывает, так как для
char смещение указателя на следующий элемент означает увеличение адреса на 1, а для
int - уже на 2 (для любого типа данных - на
sizeof(тип_данных)).
2. Все массивы располагаются в памяти сплошными блоками и
упорядоченно (младшие индексы пишутся последними), то есть, в массиве
array[4][7] элемент
array[1][0] следует
сразу за array[0][6], а раз так, то ко всем элементам можно обратиться как к одномерному массиву, лишь применив другой указатель.
Несколько раз влезь в шкуру компилятора и работа с указателями наладится.

Удачи!
(*) Ассемблер не какой-то конкретный - условный.
