Пробую программировать, часть 2 (ассемблер Эльбрус)

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

.section ".data"

.section ".text"
.global _start

_start:
{
setwd wsz = 0x4, nfx = 0x1, dbl = 0x0
}
{
addd, 0 0x0,0x1,%r1
addd, 1 0x0,0x2,%r2
}

{
addd, 0 %r1,%r2,%r3
}
{
sdisp %ctpr1, 0x1
}

! Вызываем exit
{
call %ctpr1, wbs=0x4
}

Пробую компилировать

as first_program.s -o first_program.o
first_program.s: Сообщения ассемблера:
first_program.s:8: Ошибка: unrecognized arguments `dbl=0x0' in `setwd wsz=0x4,nfx=0x1,dbl=0x0

Убрал dbl=0x0

.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
}
{
sdisp %ctpr1, 0x1
}

! Вызываем exit
{
call %ctpr1, wbs=0x4
}

Компиляция и сборка успешны

as first_program.s -o first_program.o
ld first_program.o

Но при запуске снова вижу ошибку о недопустимой инструкции

./a.out
Недопустимая инструкция

Посмотрю код objdump-ом

objdump -D a.out

a.out: формат файла elf64-e2k

Дизассемблирование раздела .text:

0000000000010078 <_start>:
10078:
setwd wsz = 0x4, nfx = 0x1

10088:
addd,0 0x0, 0x1, %dr1
addd,1 0x0, 0x2, %dr2

10098:
addd,0 %dr1, %dr2, %dr3

100a0:
sdisp %ctpr1, 0x1

100a8:
ipd 3
call %ctpr1, wbs = 0x4

Запуская программу через gdb снова получаю информацию о неверном коде операции (опкоде)

(gdb) run
Starting program: /srv/home/juvescorp/test_asm/a.out

Program received signal SIGILL, Illegal instruction

exc_illegal_opcode at 0x100d8

0x00000000000100d8 in ?? ()

Попробую сделать так же, как в простой программе сложения на Си https://vk.com/@rock_n_roll_os-razbor-operacii-slozheniya-assembler-elbrus: заменил sdisp %ctpr1, 0x1 и call %ctpr1, wbs = 0x4 на return %ctpr3 и ct %ctpr3. Добавлю также nop 5 и переставлю команды как в той простой программе, скомпилированной с Си.

.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
}

Пробую компилировать и запускать. Уже лучше

as first_program.s -o first_program.o
ld first_program.o
./a.out
Убито

Посмотрю objdump

objdump -D a.out

a.out: формат файла elf64-e2k

Дизассемблирование раздела .text:

0000000000010078 <_start>:
10078:
setwd wsz = 0x4, nfx = 0x1

10088:
addd,0 0x0, 0x1, %dr1
addd,1 0x0, 0x2, %dr2

10098:
addd,0 %dr1, %dr2, %dr3

100a0:
nop 5
return %ctpr3

100a8:
ct %ctpr3
ipd 3

Затем пробую запустить в gdb

(gdb) run
Starting program: /srv/home/juvescorp/test_asm/a.out

Program terminated with signal SIGKILL, Killed.
The program no longer exists.

Видно, что программа уничтожается. Пробую в gdb по шагам (как это делать — подсмотрел в статье http://dbp-consulting.com/tutorials/debugging/basicAsmDebuggingGDB.html)

(gdb) b _start
Breakpoint 1 at 0x10088
(gdb) r
Starting program: /srv/home/juvescorp/test_asm/a.out

Breakpoint 1, 0x0000000000010088 in _start ()
(gdb) set disassemble-next-line on
(gdb) si
0x0000000000010098 in _start ()
=> 0x0000000000010098 <_start+32>: 01 00 00 04 83 82 81 11
addd,0 %dr1, %dr2, %dr3

(gdb) si
0x00000000000100a0 in _start ()
=> 0x00000000000100a0 <_start+40>: 81 42 00 00 00 00 00 f0
nop 5
return %ctpr3

(gdb) si
0x00000000000100a8 in _start ()
=> 0x00000000000100a8 <_start+48>: 01 10 00 00 20 0c 00 c0
ct %ctpr3
ipd 3

(gdb) si

Program terminated with signal SIGKILL, Killed.
The program no longer exists.

По шагам программа проходит, но такое впечатление, что завершается не очень корректно (Program terminated with signal SIGKILL, Killed). На этом пока закончу. В дальнейшем думаю сделать так, чтобы программа завершалась корректно и посмотреть содержимое регистров по ходу выполнения программы.

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

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