ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
22 ноября
435880 Топик полностью
Ксения (24.08.2013 20:46 - 21:52, просмотров: 250) ответил mazur на Переношу асмовские наработки на си. Очередные затруднения. Есть очередь таймеров в ОЗУ. Блоки по 3 байта. Первый байт-статус. Два - счетчик. Подобные конструкции у меня часты. Также есть наработки с памятью программ.
Про указатели: Язык C в значительной степени ассеблероподобен, а потому понятие указателя фактически тождественно тому случаю в ассеблере, когда удобнее использовать адрес элемента данных (чаще массива), нежели его индекс. Именно ассеблеристы лучше всех понимают все недостатки адресации через индекс. Ведь в этом случае приходится каждый раз умножать индекс на длину элемента (если это не байт, а крупнее), а потом прибавлять это произведение к адресу начала массива. Причем, особенно противно, когда размер элемента не кратен степени двойки (2,4,8), т.к. тогда не удается заменить умножение сдвигом. Именно этот гадкий случай встретился у Мазура (3). Программист, мыслящий в образах ассеблера, конечно же, не станет каждый раз исчислять адрес элемента через его индекс, а просто будет на каждом шаге увеличивать адрес элемента, добавляя к нему его размер. Это способ прост, т.к. не требует дополнительно ни умножения, ни сдвига. Разница между C и ассемблером только в том, что указатели/поинтеры в C уже имеют тип, указываемый при их объявлении, а потому на языке C сделано так, что прибавление к указателю числа, увеличивает его не на число байт, а на число элементов. Например, если указатель инкрентировать на единичку (ptr++), то его значение увеличится на 1 (если это был указатель на массив из u08), на 2 (если это был указатель на массив из u16) или на 3 (если это был массив структур Sys_Timers_Queue). Например: struct {u08 st_flags; u16 st_cnt} Sys_Timers_Queue[ST_QUANTITY], *ptr; // здесь я добавила еще и определение указателя на структуру этого типа, которой вы наотрез оказываетесь дать имя (за что и поплатитесь в дальнейшем, т.к. из-за этого указатель вам придется держать в памяти, а не в регистре). ptr = Sys_Timers_Queue; // присваиваем указателю стартовое значение начала массива структур for(cnt=0; cnt < ST_QUANTITY; cnt++); // крутим цикл { if( ptr->st_flags & (1<<ST_UNLOCK_FLG) == 0) continue; ptr->st_flags |= (1<<ST_TIME_OUT_FLG); // else после continue избыточен ptr++; // инкремент указателя, компилятор добавит 3 байта! } А вот если бы не не были себе злобным Буратино, а послушались меня относительно имени структуры, то можно было бы записать так: register jopa *ptr = Sys_Timers_Queue; // теперь под указатель компилятор выберет регистр