Си указатели: присваивание, разыменование и перемещение по массивам / Хабр

Процедура для связи ссылочных указателей в СИ

 

В LN ссылочные указатели связываются с материалами по строкам СИ. Нужно выполнить следующие шаги:

Шаг 1. Задание ссылочных указателей

Задайте ссылочные указатели в сеансе Ссылочные указатели (tcmcs0190m000). Ссылочные указатели могут содержать, например, имена или коды, указывающие места установки компонента в изделии.

Шаг 2. Связь ссылочных указателей с изделием

Если нужно, можете связать ссылочные указатели с изделием в сеансе Ссылочные указатели по изделиям (tcibd0120m000).

Ручное связывание ссылочных указателей с изделием не является обязательным, но оно полезно для случаев, когда один или несколько ссылочных указателей применимы только для определенного изделия. Если вы на этом шаги не осуществляете ручное связывание ссылочных указателей с изделиями, ссылочные указатели будут связаны с изделием автоматически в сеансе Ссылочные указатели по изделиям (tcibd0120m000) после выполнения Шага 3.

Шаг 3. Связь ссылочных указателей с материалом по строке СИ

В сеансе Спецификация изделия (tibom1110m000) можно связать ссылочные указатели с определенной строкой СИ. Для этого нужно выбрать строку СИ и нажать в меню Ссылочные указатели по СИ. Запустится сеанс Ссылочные указатели по СИ (tibom0120m000).

Шаг 4. Выбор ссылочных указателей

Нажмите Новый в сеансе Ссылочные указатели по СИ (tibom0120m000) для привязки ссылочных указателей. Из поля Ссылочный Указатель для выбора ссылочного указателя можно выбрать следующие сеансы:

  • Если вы задали ссылочные указатели по изделию (Шаг 2), можно вызвать сеанс Ссылочные указатели по изделиям (tcibd0120m000) для выбора ссылочных указателей.
  • Если вы не задали ссылочные указатели по изделию, для выбора ссылочных указателей вызывается сеанс Ссылочные указатели (tcmcs0190m000).

Ссылочный указатель может применяться для одного или нескольких изделий по строке СИ. Нужно воспользоваться полем Кол-во в сеансе Ссылочные указатели по СИ (tibom0120m000) для указания числа изделий по строке СИ, к которым применяется ссылочный указатель.

Пример

Предположим, количество изделий по строке СИ равно шести:

  • Если вы введете 1 в поле Кол-во сеанса Ссылочные указатели по СИ (tibom0120m000), ссылочный указатель применяется только к одному изделию из всего количества по строке СИ.
  • Если вы введете 5, ссылочный указатель будет применяться только к пяти из шести изделий из строки СИ.
  • Также можно ввести, скажем, 2 для одного ссылочного указателя и 3 для другого ссылочного указателя.
  • Можно ввести 6 для ссылочного указателя, что означает, что все изделия по строке СИ должны быть установлены в одну позицию.
  • Если количество изделий по строке СИ равно шести, можно даже ввести 4 для одного ссылочного указателя и 3 для другого ссылочного указателя. Это означает, что одно из изделий по строке СИ связано с двумя ссылочными указателями.

 

 
   

НОУ ИНТУИТ | Лекция | Основы языка Си: структура Си-программы, базовые типы и конструирование новых типов, операции и выражения

< Лекция 12 || Лекция 8: 1234567

Аннотация: Лекция посвящена введению в язык Си. Объясняются общие принципы построения Си-программы: разбиение проекта на h- и c-файлы, т.е. разделение интерфейса и реализации, использование препроцессора. Приводятся базовые типы языка Си, конструкции массива и указателя, позволяющие строить новые типы, а также модификаторы типов. Рассматриваются всевозможные операции и выражения языка Си.

Ключевые слова: Си, Java, указатель, адрес, массив, программа, контроль, операционная система, API, application program, interface, компилятор, слово, оператор DEFINE, файл, прототип функции, имя функции, константы, переменная, представление, standard input, препроцессор, директива, символическое имя, понимание текста, функция, алгоритм, значение, аргумент, вещественное число, вычисленное значение, вызов функции, стандартный поток вывода, логический тип, класс, тело оператора, специальный тип данных, volatility, Intel 80286, операции, сложение, умножение, оператор присваивания, префиксные операции, сумма элементов массива, аргумент операции, эквивалентное выражение, type cast, неявное преобразование

Основы языка Си

intuit.ru/2010/edi»>В настоящее время язык Си и объектно-ориентированные языки его группы (прежде всего C++, а также Java и C#) являются основными в практическом программировании. Достоинство языка Си — это, прежде всего, его простота и лаконичность. Язык Си легко учится. Главные понятия языка Си, такие, как статические и локальные переменные, массивы, указатели, функции и т.д., максимально приближены к архитектуре реальных компьютеров. Так, указатель — это просто адрес памяти, массив — непрерывная область памяти, локальные переменные — это переменные, расположенные в аппаратном стеке, статические — в статической памяти. Программист, пишущий на Си, всегда достаточно точно представляет себе, как созданная им программа будет работать на любой конкретной архитектуре. Другими словами, язык Си предоставляет программисту полный контроль над компьютером.

Первоначально язык Си задумывался как заменитель Ассемблера для написания операционных систем. Поскольку Си — это язык высокого уровня, не зависящий от конкретной архитектуры, текст операционной системы оказывался легко переносимым с одной платформы на другую. Первой операционной системой, написанной практически целиком на Си, была система Unix. В настоящее время почти все используемые операционные системы написаны на Си. Кроме того, средства программирования, которые операционная система предоставляет разработчикам прикладных программ (так называемый API — Application Program Interface), — это наборы системных функций на языке Си.

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

В данном разделе будут приведены лишь основные понятия языка Си (и частично C++). Это не заменяет чтения полного учебника по Си или C++, например, книг [6] и [8].

Мы будем использовать компилятор C++ вместо Cи. Дело в том, что язык Си почти целиком входит в C++, т.е. нормальная программа, написанная на Си, является корректной C++ программой. Слово «нормальная» означает, что она не содержит неудачных конструкций, оставшихся от ранних версий Си и не используемых в настоящее время. Компилятор C++ предпочтительнее, чем компилятор Си, т.к. он имеет более строгий контроль ошибок. Кроме того, некоторые конструкции C++, не связанные с объектно-ориентированным программированием, очень удобны и фактически являются улучшением языка Си. Это, прежде всего, комментарии //, возможность описывать локальные переменные в любой точке программы, а не только в начале блока, и также задание констант без использования оператора #define препроцесора. Мы будем использовать эти возможности C++, оставаясь по существу в рамках языка Си.

Структура Си-программы

intuit.ru/2010/edi»>Любая достаточно большая программа на Си (программисты используют термин проект ) состоит из файлов. Файлы транслируются Си-компилятором независимо друг от друга и затем объединяются программой-построителем задач, в результате чего создается файл с программой, готовой к выполнению. Файлы, содержащие тексты Си-программы, называются исходными.

В языке Си исходные файлы бывают двух типов:

  • заголовочные, или h-файлы;
  • файлы реализации, или Cи-файлы.

Имена заголовочных файлов имеют расширение » .h «. Имена файлов реализации имеют расширения » .c » для языка Си и » .cpp «, » .cxx » или » .cc » для языка C++.

К сожалению, в отличие от языка Си, программисты не сумели договориться о едином расширении имен для файлов, содержащих программы на C++. Мы будем использовать расширение » .h » для заголовочных файлов и расширение » .cpp » для файлов реализации.

Заголовочные файлы содержат только описания. Прежде всего, это прототипы функций. Прототип функции описывает имя функции, тип возвращаемого значения, число и типы ее аргументов. Сам текст функции в h-файле не содержится. Также в h-файлах описываются имена и типы внешних переменных, константы, новые типы, структуры и т.п. В общем, h-файлы содержат лишь

интерфейсы, т.е. информацию, необходимую для использования программ, уже написанных другими программистами (или тем же программистом раньше). Заголовочные файлы лишь сообщают информацию о других программах. При трансляции заголовочных файлов, как правило, никакие объекты не создаются. Например, в заголовочном файле нельзя определить глобальную переменную. Строка описания

int x;

определяющая целочисленную переменную x, является ошибкой. Вместо этого следует использовать описание

extern int x;

означающее, что переменная x определена где-то в файле реализации (в каком — неизвестно). Слово extern (внешняя) лишь сообщает информацию о внешней переменной, но не определяет эту переменную.

Файлы реализации, или Cи-файлы, содержат тексты функций и определения глобальных переменных. Говоря упрощенно, Си-файлы содержат сами программы, а h-файлы — лишь информацию о программах.

Представление исходных текстов в виде заголовочных файлов и файлов реализации необходимо для создания больших проектов, имеющих модульную структуру. Заголовочные файлы служат для передачи информации между модулями. Файлы реализации — это отдельные модули, которые разрабатываются и транслируются независимо друг от друга и объединяются при создании выполняемой программы.

intuit.ru/2010/edi»>Файлы реализации могут подключать описания, содержащиеся в заголовочных файлах. Сами заголовочные файлы также могут использовать другие заголовочные файлы. Заголовочный файл подключается с помощью директивы препроцессора #include. Например, описания стандартных функций ввода-вывода включаются с помощью строки

#include <stdio.h>

(stdio — от слов standard input/output). Имя h-файла записывается в угловых скобках, если этот h-файл является частью стандартной Си-библиотеки и расположен в одном из системных каталогов. Имена h-файлов, созданных самим программистом в рамках разрабатываемого проекта и расположенных в текущем каталоге, указываются в двойных кавычках, например,

#include "abcd.h"

Препроцессор — это программа предварительной обработки текста непосредственно перед трансляцией. Команды препроцессора называются директивами

. Директивы препроцессора содержат символ диез # в начале строки. Препроцессор используется в основном для подключения h-файлов. В Си также очень часто используется директива #define для задания символических имен констант. Так, строка

#define PI 3.14159265

задает символическое имя PI для константы 3.14159265. После этого имя PI можно использовать вместо числового значения. Препроцессор находит все вхождения слова PI в текст и заменяет их на константу. Таким образом, препроцессор осуществляет подмену одного текста другим. Необходимость использования препроцессора всегда свидетельствует о недостаточной выразительности языка. Так, в любом Ассемблере средства препроцессирования используются довольно интенсивно. В Си по возможности следует избегать чрезмерного увлечения командами препроцессора — это затрудняет понимание текста программы и зачастую ведет к трудно исправляемым ошибкам. В C++ можно обойтись без использования директив #define для задания констант. Например, в C++ константу PI можно задать с помощью нормального описания

const double PI = 3. 14159265;

Это является одним из аргументов в пользу применения компилятора C++ вместо Си даже при трансляции программ, не содержащих конструкции класса.

Дальше >>

< Лекция 12 || Лекция 8: 1234567

Сборка

— куда указывает указатель SI, когда указано, что он указывает на смещение?

Заранее извиняюсь, если вопрос дублируется. Меня немного смущает следующий код:

 list db 80h, 70h, 60h, 50h, 40h, 30h, 20h
       mov si, офсетный список
       двигаться аль, [си]
повторять: вкл си
       добавить al,[si]
       ООО Репит
плавник:
 

Я знаю, что

jnc указывает на то, что мы выйдем из этого цикла, когда не будет переполнения переноса, т. е. CF = 0 . Поскольку si должен указывать на индекс первого элемента списка, не будет ли это 80h? И затем, если si увеличивается, он должен указывать на 70h. Если сложить их вместе, ответ должен быть F0, верно? Однако, когда я запускаю фрагмент кода, я получаю значение AL равным 50. Как это возможно? Что мне не хватает? Спасибо всем заранее!

  • указатели
  • сборка
  • индексация
  • x86
  • память-сегментация

1

Я знаю, что jnc указывает, что мы выйдем из этого цикла, когда не будет переполнения переноса, т. е. CF = 0.

Это неверно. JNC перескочит, если CF=0, что значит перескочит, если нет

беззнакового переполнения .

Поскольку предполагается, что si указывает на индекс первого элемента списка, не будет ли это 80h? И затем, если si увеличивается, он должен указывать на 70h. Если сложить их вместе, ответ должен быть F0, верно?

Пока да.

Однако, когда я запускаю фрагмент кода, я получаю значение AL равным 50. Как это возможно?
Что я упускаю?

Возвращаемое значение 50h равно

 80h + 70h + 60h = 50h + флаг CARRY (беззнаковое переполнение). 
 

Пошагово это

 80h + 70h = F0h (CF = 0 = JUMP)
F0h + 60h = 50h (CF = 1 = НЕТ ПЕРЕХОДА = ВЫХОД ЦИКЛ)
 

Итак, последнее добавление устанавливает флаг CARRY на 1 из-за беззнаковое переполнение из FFh в 00h (F0h + 0Fh в F0h + 10h (и, наконец, 60h — 10h = 50h)). Поскольку флаг CARRY установлен, условный переход JNC проходит, а AL содержит «переполненное» значение 50h.

Чтобы ответить на вопрос заголовка (который почти не связан с остальной частью вашего вопроса):

Куда указывает указатель SI, если указано, что он указывает на смещение?

В модели сегментированной памяти x86 рядом с указателями — это смещений относительно базы сегмента. mov si, символ OFFSET устанавливает SI в часть смещения адреса seg:off символа .

Если символ является меткой в ​​разделе данных вашей программы, и вы используете [SI] , в то время как DS база сегмента = начало этого раздела, тогда [SI] дает вам байты ) по адресу символ в качестве операнда памяти.

SI не указывает на смещение, это содержит смещение после mov si, символ OFFSET . Этот является указателем.


В простой плоской модели памяти (например, 32- или 64-битном коде) все использует основание = 0, поэтому смещение = линейный адрес.

В 16-битном коде с «крошечной» моделью памяти (например, .com ) CS=DS=ES=SS, поэтому все ссылки на память используют одну и ту же базу. Опять же, только 16-битное смещение работает как полный указатель. Фактическая база сегмента не имеет значения, потому что все относительно нее.

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя адрес электронной почты и пароль

Опубликовать как гость

Электронная почта

Обязательно, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Сборка

— В чем практическая разница между регистрами SI и DI?

спросил

Изменено 9лет, 6 месяцев назад

Просмотрено 63к раз

Не понимаю в чем разница.

  • сборка
  • x86
  • регистры процессора

0

Когда вы используете такие инструкции, как movsb, si считается регистром нашего источника s , а di — регистром назначения d . Но они оба являются обычными регистрами x86.

Моя сборка немного заржавела, но у одного индекс источника, у другого индекс назначения. Такая инструкция, как movsb , скопирует байт из ячейки памяти, на которую указывает SI , и переместит его в ячейку памяти, на которую указывает DI , а затем увеличит оба байта, поэтому, если вы хотите скопировать байт, хранящийся в SI+1 до DI+1 , требуется только дополнительная инструкция movsb.

SI означает исходный индекс. Исходный индекс используется в качестве указателя на текущий символ, считываемый в строковой инструкции (LODS, MOVS или CMPS).

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *