В прошлый раз были разобраны команды для отображения регистров.
Сейчас я попробую посмотреть, как меняются значения регистров по ходу выполнения программы. Смотреть буду через отладчик gdb.
Исходный код программы такой
.section ".data"
.section ".text"
.global _start
_start:
{
setwd wsz = 0x4, nfx = 0x1
}
{
addd, 0 0x0,0x1,%r1
addd, 1 0x0,0x2,%r2
}
{
addd, 0 %r1,%r2,%r3
}
{
nop 5
return %ctpr3
}
! Вызываем exit
{
ct %ctpr3
}
Запустил отладчик на этой программе
$ gdb a.out
Ставлю точку останова, метку _start
(gdb) b _start Breakpoint 1 at 0x10088
Запускаю
(gdb) r Starting program: /srv/home/juvescorp/test_asm/a.out Breakpoint 1, 0x0000000000010088 in _start ()
Смотрю состояние нужных регистров
info all-registers ctpr3 0x1e00000000000000 2161727821137838080 ta_base 0x0 0 ta_tag 0x0 0 opc 0x3 3 ipd 0x3 3 ... r0 <00> 0x0 0 r1 <00> 0x10078 65656 r2 <00> 0x20370 131952 r3 <00> 0x0 0 ... wd 0x4000400610 274882102800 base 0x610 1552 size 0x40 64 psize 0x40 64 fx 0x0 0 ... ip 0x10088 65672
Предполагаемые нужные регистры — r1, r2, r3, wd, ctpr3, ip
r1, r2, r3 — регистры общего назначения. Два из них будут слагаемыми, а в одном будет храниться сумма
wd — это параметры регистрового окна, как я понял.
ctpr3 — используемый в программе регистр, в котором будет адрес перехода
ip — instruction pointer, счётчик команд. Показывает, на какой команде (по какому адресу) программа сейчас находится.
Делаю шаг
(gdb) si 0x0000000000010098 in _start ()
Смотрю регистры
info all-registers ... ctpr3 0x1e00000000000000 2161727821137838080 ta_base 0x0 0 ta_tag 0x0 0 opc 0x3 3 ipd 0x3 3 ... r1 <00> 0x1 1 r2 <00> 0x2 2 r3 <00> 0x0 0 ... wd 0x4000400610 274882102800 base 0x610 1552 size 0x40 64 psize 0x40 64 fx 0x0 0 ... ip 0x10098 65688
Видно, что изменились значения регистров r1, r2, ip. r1 теперь равен 1, r2 — равен 2. Счётчик команд ip — 0x10098 или 65688 в десятичной системе
Делаю следующий шаг
(gdb) si 0x00000000000100a0 in _start ()
Смотрю регистры
info all-registers
...
ctpr3 0x1e00000000000000 2161727821137838080
ta_base 0x0 0
ta_tag 0x0 0
opc 0x3 3
ipd 0x3 3
...
r1 <00> 0x1 1
r2 <00> 0x2 2
r3 <00> 0x3 3
...
wd 0x4000400130 274882101552
base 0x130 304
size 0x40 64
psize 0x40 64
fx 0x0 0
...
pc 0x100a0 65696
...
ip 0x100a0 65696
Здесь изменилось значение регистров r3, ip, wd.
r3 стал равен сумме r1 и r2 — трём (3). Ещё заметил, что есть регистр pc (program counter, программный счётчик или счётчик программы), равный значению ip — 0x100a0 или 65696 в десятичной системе.
wd был 0x4000400610, стал — 0x4000400130. Конкретно изменилась только часть base. Она была равна 0x610, стала равна 0x130. Как конкретно меняется этот регистр и каким образом меняются его значения — пока непонятно. Вероятно, в дальнейшем разберусь.
Делаю следующий шаг
(gdb) si 0x00000000000100a8 in _start ()
Смотрю регистры
info all-registers
...
ctpr3 0x1e80000000000000 2197756618156802048
ta_base 0x0 0
ta_tag 0x2 2
opc 0x3 3
ipd 0x3 3
...
r1 <00> 0x1 1
r2 <00> 0x2 2
r3 <00> 0x3 3
...
wd 0x4000400130 274882101552
base 0x130 304
size 0x40 64
psize 0x40 64
fx 0x0 0
...
pc 0x100a8 65704
...
ip 0x100a8 65704
Видно, что изменились регистры ctpr3 и pc=ip.
ctpr3 имел значение 0x1e00000000000000. Теперь он содержит 0x1e80000000000000. Вероятно, изменилась только часть ta_tag. Она была равна нулю(0), теперь — 2
Делаю шаг и на этом всё, программа была уничтожена
(gdb) si Program terminated with signal SIGKILL, Killed. The program no longer exists.
В следующий раз скорей всего попробую сделать поудобнее: вывести значения регистров на панель. Плюс планирую сделать так, чтобы программа завершалась корректно.
