3. Локальные переменные

Занятие 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
  • операнды в стек помещаются в том порядке, в каком они указаны в сигнатуре метода

Задание #

  1. Перепишите процедуру нахождения расстояния между точками, используя:
  • локальные переменные
  • ввод значений координат пользователем. Подсказка – для перевода строк в числа можно использовать статический метод
float64 [mscorlib]System.Double::Parse(string)