изучение ARM



На  этот шаг подтолкнул один камрад JinX и мое безделье. Стал искать информацию об опкодах и симулятор. Нашелся ArmSim# и часть описаний программы. Вот только новая версия симулятора 2.0 отличается от описаний. Началось все не легко, в 10ке х64 заshitник не позволял установить программу. Не проблема, распаковал .msi, симулятор запустился. Первое неудобство - программа только открывает исходник, но не позволяет редактировать текст.Взял пример с руководства:

@ A simple ARM assembly program.
MOV r2, #10@ Load the value 10 into register r2
MOV r3, #2@ Load the value 2 into register r3
MUL r1, r2, r3 @ Compute r2*r3 and store in r1 (10*2 = 20)
MOV r0, #1@ Load 1 into register r0 (stdout handle)
SWI 0x6b@ Print integer in register r1 to stdout
SWI 0x11@ Stop program execution

по шагам прога работает, но не выводит на экран результат и ругается на некий некорректный вызов. Оставил решение проблемы на утро, проверю на 7ке 32бит. С утра то же самое. Стал искать причину - нужно указать в настройках File->Preferences на закладке Plugins  поставить галку на Legacy SWI extension instructions. Ага, почти работает, вывод текста появляется то ли в закладке Console, то ли stdin.

Описание опкодов нашлось в Google, стал понемногу изучать, чтобы не забивать голову. Позже вычитал, что проц не может обращаться по указанному адресу памяти, удобнее использовать чтение через регистр. А регистров всего 16, у трех есть свое назначение, о котором можно тоже узнать в руководстве.

Что бы такое написать? Конечно же, не печать Hello,world! Я решил попробовать написать зеркальное отображение строки. И вот что получилось:

.text
ldr r0,=tt
swi 0x02 ;печать текста r0=адрес, строка завершается 0.
ldr r0,=crlf
swi 0x02
@ reverse string
ldr r10,=tt ;r10=адрес строки
ldr r11,=et-2;r11=адрес конца строки
rs:
ldrb r0,[r10];считать байт по адресу r10 и поместить в r0
ldrb r1,[r11]
strb r0,[r11];записать байт из r0 по адресу r11
strb r1,[r10]
add r10,r10,#1;r10-r10+1
sub r11,r11,#1;r11=r11-1
cmp r10,r11;r10=r11?
beq exr; если да, то выход из цикла
ble rs; если r10<r11, переход на цикл
exr:
ldr r0,=tt @print again
swi 0x02
SWI 0x11 @ Stop program execution
crlf:  .byte 0x0D,0x0A,0
tt: .ascii "1234" @"Hello, ARM!",0
.byte 0
et:

Ох, работает! Но когда я читал пример программы для GBA, я увидел другой формат опкода, поэтому программу пришлось переписать:

.text
ldr r0,=tt
swi 0x02

ldr r0,=crlf
swi 0x02

@ reverse string
ldr r10,=tt
ldr r11,=et-2

rs:
ldrb r0,[r10]
ldrb r1,[r11]
strb r0,[r11],#-1;здесь после записи байта из регистра r0 в память у r11 вычитается 1
strb r1,[r10],#1 ;добавляется 1
@add r10,r10,#1
@sub r11,r11,#1
cmp r10,r11
beq exr
ble rs
exr:
ldr r0,=tt @print again
swi 0x02

SWI 0x11 @ Stop program execution
crlf:  .byte 0x0D,0x0A,0
tt: .ascii "1234" @"Hello, ARM!",0
.byte 0
et:

После возни с кодом я начал снова читать доки, и потом вернулся к GBA. Вышло 256б интро, о создании которого я напишу позже. До кучи нашел рабочий эмулятор Acorn Archimedes, но ассемблер пока не готов, хочу попробовать накодить что-нибудь.

Комментарии