Занятие 3. Локальные переменные #
В предыдущем занятии мы использовали для работы и хранения промежуточных вычислений стек метода. Однако, это не единственный вариант работы с памятью в CIL.
Для каждого метода в CIL, как и во многих языках высокого уровня можно объявлять локальные переменные. Для этого используется директива .locals общий синтаксис которой таков:
.locals [init] (<тип переменной> [<имя переменной>], … )
Если указать ключевое слово init, то все переменные будут инициализированы значениями по умолчанию. Для того чтобы метод был верифицируемым, указание этого слова обязательно.
Имя переменной может не указываться, тогда к ней нужно будет обращаться по номеру (начиная с 0 от начала метода). В одном методе может быть несколько объявлений локальных переменных.
Для работы с переменными используются инструкции:
Операция | Описание |
---|---|
ldloc | загрузка локальной переменной в стек |
stloc | сохранение вершины стека в локальную переменную и удалениез начения из стека |
Далее приводится программа, которая демонстрирует использование локальных переменных. В ней происходит запрос строки, разделенной пробелами, а затем выделяется и печатается второе слово:
.assembly Step_3 {}
.method void main()
{
.entrypoint
.maxstack 10
.locals init (string str, int32 startWord, int32 endWord)
ldstr "Введите строку из нескольких слов, разделенных пробелом"
call void [mscorlib]System.Console::WriteLine(string)
call string [mscorlib]System.Console::ReadLine()
stloc str
ldloc str
ldstr " "
call instance int32 [mscorlib]System.String::IndexOf(string)
ldc.i4 1
add
stloc startWord
ldloc str
ldstr " "
ldloc startWord
call instance int32 [mscorlib]System.String::IndexOf(string, int32)
stloc endWord
ldloc str
ldloc startWord
ldloc endWord
ldloc startWord
sub
call instance string [mscorlib]System.String::Substring(int32, int32)
call void [mscorlib]System.Console::WriteLine(string)
ret
}
Как обычно, несколько дополнительных комментариев:
- для работы со строками в программе используются методы класса System.String: IndexOf (2 варианта) и Substring. Все эти методы являются экземплярными, т.е. должны вызываться для уже существующего объекта. Поэтому чтобы вызвать эти методы делается следующее:
- первым аргументом в стек загружается строка, которая и будет этим экземпляром. При этом, среди параметров методов сама первая строка не указывается, т.е. как и в языках высокого уровня, она передается неявно
- при вызове метода указывается ключевое слово instance.
- методы IndexOf ищут в строке первое вхождение указанной подстроки и возвращают его индекс. Первый вариант метода ищет от начала строки, второй – от заданной позиции.
- метод Substring возвращает подстроку, начиная с указанной позиции и имеющей заданную длину
- все индексы в строках от 0
- операнды в стек помещаются в том порядке, в каком они указаны в сигнатуре метода
Задание #
- Перепишите процедуру нахождения расстояния между точками, используя:
- локальные переменные
- ввод значений координат пользователем. Подсказка – для перевода строк в числа можно использовать статический метод
float64 [mscorlib]System.Double::Parse(string)