Перейти к содержанию
Old Phone Forum
  • Вход

    Вы сейчас не залогинены на форуме.

    Для возможности комментариев, загрузки файлов, подписок на ответы - вам надо войти.

Удобные функции & макросы для написания патчей на ассемблере


Рекомендуемые сообщения

В этой теме предлагаю выкладывать то, что так облегчает нам(патчмейкерам) помогает при написании патчей :(

А именно - различные функции и макросы, которые могут помочь новичкам и не только.

 

Если платформа для функции не универсальная, то просьба об этом конкретно отписаться...

 

А теперь, начнем :))

Макрос Set_St_String

Платформа - Sysol/Swift.

;Макрос для замены стандартного текстового ресурса (не Extended Api)
;Написан для упрощения переноса на другие прошивки без использования директивы ".replace"
;Set_St_String Адрес_Таблицы_Языка Индекс_Языкового_Ресурса Адрес_Новой_Строки

.macro Set_St_String text_table_adress index_str adress_new_str
.org \text_table_adress + 4*(\index_str)
.align 1
DCD \adress_new_str
.endm

 

Макрос ExternalFunc

Платформа - Sysol/Swift.

;Знакомый многим макрос для создания перехода вида (взят из руководства BinEdit)
;push {r0,r1}
;ldr r0, =0x00123456
;str r0, sp,4
;pop {r0,pc}
;Использование - ExternalFunc MyFunc 0x123456
;Для вызова - BL .MyFunc

.macro ExternalFunc name adress
.align 2
.\name:
push {r0,r1}
ldr r0,_\name
str r0, [sp,4]
pop {r0,pc}
_\name: .word \adress+1
.endm

 

Функция GetSelectedNum

Платформа - Sysol.

/*
=====================================================================
int GetSelectedNum(void) 
Функция получения выбранного пункта меню
=====================================================================
*/
GetSelectedNum:
PUSH 	{LR}
LDR R0, =DspList
LDRH R0, [R0, #32]
POP	{PC}
.data

 

Функция Menu_AddItem

Платформа - Sysol.

/*
=====================================================================
void Menu_AddItem(char *Str, int num_item, *DspList)
Функция добавления пункта меню
=====================================================================
*/
Menu_AddItem:			
PUSH 	{R2-R4, LR}
SUB 	SP, SP, #4
MOV	R4, R2
MOV	R3, R0
MOV	R0, #0
STR	R0, [SP]
MOV	R2, #2
MOV	R0, R4
BL	AddList						
ADD 	SP, SP, #4		
POP	{R2-R4, PC}

 

 

Функция Menu_AddItemHint

Платформа - Sysol.

/*
=====================================================================
void Menu_AddItemHint(char *Hint_Str, int num_item, *DspList)
Функция добавления подсказки для пункта меню
=====================================================================
*/	
Menu_AddItemHint:
PUSH 	{R2-R4, LR}
SUB 	SP, SP, #4
MOV	R4, R2	
MOV	R3, R0
MOV	R0, #0
STR	R0, [SP]
MOV	R2, #3
MOV	R0, R4
BL	AddList
ADD 	SP, SP, #4		
POP 	{R2-R4, PC}

 

Функция My_Menu_AddIcon

Платформа - Sysol.

/*
=====================================================================
void My_Menu_AddIcon(int IconTimerId, int num_item, *DspList)
Функция добавления иконки для пункта меню
=====================================================================
*/	
My_Menu_AddIcon:
PUSH 	{R2-R4, LR}
SUB 	SP, SP, #4
MOV	R4, R2
MOV 	R3, #0
STR	R0, [SP]
MOV	R2, #4
ADD 	R0, R4, #0
BL	AddList						
ADD 	SP, SP, #4
POP 	{R2-R4, PC}

 

Функция SetCheckListItem

Платформа - Sysol.

/*
=====================================================================	
void SetCheckListItem(int Val, int ItemNum)
Устанавливает галку для меню типа CheckList
=====================================================================
*/
SetCheckListItem:
PUSH	{R2, LR}
MOV	R2, #0x48
MUL	R1, R2

LDR	R2, =DspList
LDR 	R2, [R2, #0x24]

ADD	R1, R1, R2
STRB	R0, [R1, #8]
POP	{R2, PC}

 

GetCheckListItem

Платформа - Sysol.

/*
=====================================================================
int GetCheckListItem(int ItemNum)
Получает состояние галки для меню типа CheckList
=====================================================================
*/
GetCheckListItem:
PUSH	{R1-R2, LR}
MOV	R1, R0

MOV	R2, #0x48
MUL	R1, R2

LDR	R2, =DspList
LDR 	R2, [R2, #0x24]

ADD	R1, R1, R2
LDRB	R0, [R1, #8]
POP	{R1-R2, PC}

 

HexToInt

Платформа - Sysol.(Swift под? Просьба проверить)

/*
=====================================================================
int HexToInt(*char HexStr)
Переводит hex строку длиной до 8-ми символоа включительно в int число.
При ошибке выдает 1 в R1.
=====================================================================
*/	
HexToInt:
PUSH	{R2-R5, LR}
MOV		R5, R0

@Перевод символов в верхний регистр	
BL		libc_ucase	  @char* libc_ucase(char *str)

@Получение длины HexStr	
	BL		strlen
MOV		R3, R0			@R3 = len

MOV		R4, #0			@Result

HexToInt_Loop:
LSL		R4, R4, #4		@Result = Result * 0x10	
LDRB		R0, [R5]

CMP		R0, '0'
BLT		HTI_ErrorExit

CMP		R0, '9'
BLE		HTI_ConvertCount

CMP		R0, 'A'
BLT		HTI_ErrorExit

CMP		R0, 'F'
BLE		HTI_ConvertLetter

B		HTI_ErrorExit

HexToInt_Continue:
ADD		R4, R4, R0

SUB		R3, #1
ADD		R5, #1

CMP		R3, #0			@if len = 0 then
BNE		HexToInt_Loop

Exit_HexToInt_Ok:
MOV		R1, #0
MOV		R0, R4

Exit_HexToInt:
POP		{R2-R5, PC}

HTI_ConvertCount:
	SUB		R0, #0x30
B		HexToInt_Continue

HTI_ConvertLetter:
	SUB		R0, #0x37
B		HexToInt_Continue

HTI_ErrorExit:
	MOV		R0, #0
MOV		R1, #1
B		Exit_HexToInt

  • Like 2
Ссылка на комментарий
Поделиться на другие сайты

Вот может кому пригодиться, все адреса только для X100.

 

Полезные функции из патча PhoneBookAndSms_pack

;Function CREATE_LIST;

;in r0-колличество пунктов меню;

;in r1-тип меню

.equ DM_CREATE_LIST 0x00598FDC

 

;Function Get_index

;out r0-индекс пункта

.equ DM_Get_index 0x00598FEC

 

 

 

;Function Add_index

;параметры в r0(адрес на буфер)

;1 байт-0 или 1, ели 1 то значит в r1 адрес на строку, ели 0 то значит индекс

;2 байт- ели 0 то подсказки нет елси 1, то по смещению 2 от r0, находиться адрес на строку с подсказкой

;3,4-индес меню(слово)

;5,6,7,8-адрес подсказки подсказка(двойное слово)

 

;in r1-идекс текст. рес или адрес на строку

;in r2-0

.equ DM_Add_index 0x0598FF4

 

 

;Function Pos_inText

;r0-текст для поиска

;r1-искомый текст

.equ Pos_inText 0x0599346

 

 

 

Пример создания меню в патче TxtReader 1.2 по правой кнопке.

 

TR_RSK_Menu:

push r0-r7,lr

sub sp,0x12

 

mov r0,0

BL 0x000B677C ;SetCurList ;устанавливаем курсор в нулевое положение

 

 

mov r0,3

MOV R1,1 ;R1 = 1

BL DM_CREATE_LIST ;создаем обычное меню из 3-х пунктов

 

 

mov r4,0

;запускаем цикл добавления пунктов

TR_RSK_Menu_menuADD:

 

mov r1,1

mov r0,sp

STRB r1,r0,0

mov r1,0

STRB r1,r0,1

 

 

;индекс

STRH r4,r0,2

 

 

mov r0,r4

BL GetRSK_MenuCaption ;функция получения имени меню по индексу

mov r1,r0

mov r0,sp

mov r2,0

BL DM_Add_index

 

add r4,1

cmp r4,3

BGE TR_RSK_Menu_ex ;если счетчик равен 3 то выходим из функции

b TR_RSK_Menu_menuADD

 

 

TR_RSK_Menu_ex:

ADD sp,0x12

pop r0-r7,pc

 

;in r0-индекс

;out r0-String MenuCaption

GetRSK_MenuCaption:

push lr

cmp r0,0

BEQ GetRSK_MenuCap_1

cmp r0,1

BEQ GetRSK_MenuCap_2

cmp r0,2

BEQ GetRSK_MenuCap_3

b GetRSK_MenuCaption_ex

 

GetRSK_MenuCap_1:

ADR r0="Найти далее"

b GetRSK_MenuCaption_ex

 

GetRSK_MenuCap_2:

ADR r0="Закладки"

b GetRSK_MenuCaption_ex

 

GetRSK_MenuCap_3:

ADR r0="Кодировка"

b GetRSK_MenuCaption_ex

 

 

GetRSK_MenuCaption_ex:

pop pc

 

Не забывайте что это еще не все, нужно еще прописать появление меню и захват обработки событий. Это делается с помощью МСС инструкций .

;##############################################################

 

 

 

 

;Экспортируемые функции в патче TxtReader 1.2

;Table:

;TR_OpenFile

;ANSIItoUTF8

;mystrlen

;DisStatrLogFun

.start 0x6DCC48

 

.long TR_OpenFile+1 ;Открытие файла в просмоторщике

;in r0-file name

;in r1-флаг копирования имени в собственный буфер(1-копировать, 0-нет)

 

;in r1-Ansii

;in r0-Utf8

.long ANSIItoUTF8+1 ;Преобразование строки Ansii в Utf8

 

;in r0-Utf8

.long mystrlen+1 ;Длинна строки UTF8 учитывая рус. символы

 

;r0-строка

;r1-y

.long DisStatrLogFun+1 ;Выводит на экран "строку" с положением y

 

 

Пример открытия файла *.txt в патче Файловый менеджер 0.1

.equ TxtR_ExpFunTable 0x6DCC48 ;Адрес таблицы экспортируемых функций в патче txtreader

FM_OpenFile_txt:

push lr

LDR r3,=TxtR_ExpFunTable

mov r0,0

LDR r3,r3,r0 ;TR_OpenFile

 

LDR r0,=ListSelFullName

mov r1,1

BL _call_via_R3

 

pop pc

 

_call_via_R3:

BX R3

Ссылка на комментарий
Поделиться на другие сайты

Продолжаем :)

 

Кое-какие константы

Платформа - Sysol

;List Types(Типы меню для CreateList)
.equ NormalList		 #1
.equ IconList		   #2
.equ RadioList		   #3
.equ CheckList		   #4
.equ CheckListPiracy #14

;fmOpen Types(mode для ffsOpenFile)
.equ fmOpenRead 					#2
.equ fmOpenWrite					#4

 

Функции по прямой работе с железом телефона

 

Hw_DisplayBackLightEnable

Платформа - Sysol(SGH-X100)

/*
=====================================================================
Включает подсветку дисплея
void Hw_DisplayBackLightEnable(void)
=====================================================================
*/
Hw_DisplayBackLightEnable:
PUSH	{R0-R2, LR}
LDR		R0, =0xFFFF8400
LDRH	R1, [R0, #10]
MOV		R2, #0x10
ORR		R1, R2
STRH	R1, [R0, #10]
POP		{R0-R2, PC}
.data

 

Hw_DisplayBackLightDisable

Платформа - Sysol(SGH-X100)

/*
=====================================================================
Выключает подсветку дисплея
void Hw_DisplayBackLightDisable(void)
=====================================================================
*/
Hw_DisplayBackLightDisable:
PUSH	{R0-R2, LR}
LDR		R0, =0xFFFF8400
LDRH	R1, [R0, #10]
MOV		R2, #0x10
BIC		R1, R2
STRH	R1, [R0, #10]
POP		{R0-R2, PC}
.data

 

 

Hard_KeypadBacklightOff

Платформа - Sysol(SGH-X100)

/*
=====================================================================
Выключение подсветки клавиатуры
void Hard_KeypadBacklightOff(void)
=====================================================================
*/
Hard_KeypadBacklightOff:
PUSH	{R0-R1, R3, LR}
LDR		R0, =0xFFFF8400
LDRH	R1, [R0, #10]
MOV		R3, #0xFF
ADD		R3, #0x1
BIC		R1, R3
STRH	R1, [R0, #10]
POP		{R0-R1, R3, PC}
.data

 

Hard_KeypadBacklightOn

Платформа - Sysol(SGH-X100)

/*
=====================================================================
Включение подсветки клавиатуры
void Hard_KeypadBacklightOn(void)
=====================================================================
*/
Hard_KeypadBacklightOn:
PUSH	{R0-R1, R3, LR}
LDR		R0, =0xFFFF8400
LDRH	R1, [R0, #10]
MOV		R3, #0xFF
ADD		R3, #0x1
ORR		R1, R3
STRH	R1, [R0, #10]
POP		{R0-R1, R3, PC}
.data

Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

Вношу свою скромную лепту...

 

Целочисленная арифметика

 

Модуль разности:

 

ABSSub:
cmp r0,r1
blt ABSSubLeth
sub r0,r0,r1
b exitABSSub
ABSSubLeth:
sub r0,r1,r0
exitABSSub:
bx lr

 

Деление (простое):

 

myDel:
push {r1-r7,lr}
mov r2,r0
mov r0,0
loopMyDel:
sub r2,r1
bmi exitMyDel
add r0,1
b loopMyDel
exitMyDel:
pop {r1-r7,pc}

 

Деление (усложненное):

 

MyDel:
push {r2,r3,lr}
mov r2,0
LoopDel:
mov r3,r0
mul r3,r2
add r2,1
cmp r3,r1
blt LoopDel
cmp r3,r1
beq DelSub
sub r3,r1
sub r2,1
mul r0,r2
sub r0,r1,r0
cmp r3,r0
bge DelSub
DelNotSub:
add r2,1
DelSub:
mov r0,r2
pop {r2,r3,pc}

 

Корень квадратный (используется хитрый прием, но работает 100% ):

 

MySQRT:
push {r5-r7,lr}
mov r5,0
mov r6,1
startSQRT:
add r5,r6
add r6,2
cmp r5,r0
blt startSQRT
lsr r6,1
beq SQRTWithoutRound
mov r5,r6
mul r5,r5
sub r5,r0
sub r7,r6,1
mul r7,r7
sub r7,r0,r7
cmp r5,r7
ble SQRTWithoutRound
sub r6,1
SQRTWithoutRound:
mov r0,r6

pop {r5-r7,pc}

 

Расстояние между двумя точками (r0=x1,r1=y1,r2=x2,r3=x3):

GetLength:

push {r1-r4,lr}

bl ABSSub

mul r0,r0

mov r4,r0

mov r0,r2

mov r1,r3

bl ABSSub

mul r0,r0

add r0,r4

bl MySQRT

pop {r1-r4,pc}

 

Графика

 

Платформеннонезависимые:

 

Рисует "блик".

r0=centerX

r1=centerY

r2=radius

DrawBlick:
push {r0-r7,lr}
sub sp,16
str r2,sp,8
str r3,sp,12
add r6,r0,r2
cmp r6,128   ;Вместо 128 используйте ширину экрана в пикселях
ble RightNormal
mov r6,128   ;Вместо 128 используйте ширину экрана в пикселях
RightNormal:
add r7,r1,r2
cmp r7,128   ;Вместо 128 используйте высоту экрана в пикселях
ble DownNormal
mov r7,128  ;Вместо 128 используйте высоту экрана в пикселях
DownNormal:

str r6,sp
str r7,sp,4

sub r6,r0,r2
bpl LeftNormal
mov r6,0
LeftNormal:
sub r7,r1,r2
bpl UpNormal
mov r7,0
UpNormal:

mov r4,r0
mov r5,r1
mov r2,r6
BlickLoop:
mov r3,r5
mov r1,r2
push r2
mov r2,r7
mov r0,r4
bl GetLength
pop r2
mov r1,32
mul r1,r0
ldr r0,sp,8
bl MyDel
mov r1,32
sub r1,r0
bpl BlickNormal
mov r1,0
BlickNormal:
mov r0,r2
mov r2,r1
mov r1,r7
ldr r3,sp,12
bl SetPixelAlpha   ;Используется платформеннозависимая функция  (будет показан пример для сисол)	add r2,r0,1
ldr r3,sp
cmp r2,r3
ble BlickLoop
mov r2,r6
ldr r3,sp,4
add r7,1
cmp r7,r3
ble BlickLoop
add sp,16
pop {r0-r7,pc}

 

Функции рисования различных прямоугольников:

 

;Инвертированный
;r0=x
;r1=y
;r2=w
;r3=h
DrawInvertRectangle:
push {r0-r3,LR}
add r2,r0
add r3,r1
LoopDrawInvertRectangle:
bl SetPixelInvert;Платформеннозависимая функция (будет показан пример для сисол)
add r0,1
cmp r0,r2
blt LoopDrawInvertRectangle
ldr r0,sp
add r1,1
cmp r1,r3
blt LoopDrawInvertRectangle	
pop {r0-r3,PC}

;Осветленный
;r0=x
;r1=y
;r2=w
;r3=h
;r4=коэффициент осветления/затемнения (0-31 - осветление, 32-64 - затемнение)
DrawBrightnessRectangle:
push {r0-r4,LR}
add r4,r2,r0
add r3,r1
ldr r4,[sp+8]
LoopDrawBrightnessRectangle:
bl SetPixelBrightness
add r0,1
cmp r0,r4
blt LoopDrawBrightnessRectangle
ldr r0,sp
add r1,1
cmp r1,r3
blt LoopDrawInvertRectangle	
pop {r0-r4,PC}
;r0=x
;r1=y
;r2=коэффициент осветления/затемнения (0-31 - осветление, 32-64 - затемнение)
SetPixelBrightness:
push {r0-r3,lr}
ldr r3,=0xffff
cmp r2,0x20
blt setBrPixel
mov r3,0xffff
sub r2,0x20
setBrPixel:
bl SetPixelAlpha
pop {r0-r3,pc}

;С прозрачностью
;r0=x
;r1=y
;r2=w
;r3=h
;r4=color
;r5=alpha
DrawAlphaRectangle:
push {r0-r3,r6,r7,LR}
add r2,r0
mov r6,r2
add r3,r1
mov r7,r3
mov r2,r5
mov r3,r4
LoopDrawAlphaRectangle:
bl SetPixelAlpha;Платформеннозависимая функция (будет показан пример для сисол)
add r0,1
cmp r0,r6
blt LoopDrawAlphaRectangle
ldr r0,sp
add r1,1
cmp r1,r7
blt LoopDrawAlphaRectangle	
pop {r0-r3,r6,r7,PC}

 

Функция прорисовки границ инвертированного прямоугольника (по аналогии можно сделать и для полупрозрачного, и для любого другого прямоугольника):

r0=left

r1=top

r2=width

r3=height

 

DrawInversBox:
push {r0-r4,lr}
cmp r2,1
bne DIB1
bl DrawVLine
b exitDIB

DIB1:
cmp r3,1
bne DIB
bl DrawHLine
b exitDIB

DIB:
sub r4,r3,1
bl DrawHLine

add r1,r4
bl DrawHLine

sub r1,r4
sub r4,r2,1
bl DrawVLine

add r0,r4
bl DrawVLine
exitDIB:
pop {r0-r4,pc}

DrawVLine:
push {r1,r3,lr}
add r3,r1
LoopVLine:
bl SetPixelInvert
add r1,1
cmp r1,r3
blt LoopVLine
pop {r1,r3,pc}

DrawHLine:
push {r0,r2,lr}
add r2,r0
LoopHLine:
bl SetPixelInvert
add r0,1
cmp r0,r2
blt LoopHLine
pop {r0,r2,pc}

 

Платформеннозависимые:

 

Функции для предыдущих примеров (x100):

;r0=x
;r1=y
SetPixelInvert:
push {r0-r2,lr}
lsl r0,1
lsl r1,8
add r1,r0
ldr r0,=vScreenMem
add r1,r0
ldrh r2,r1
mov r0,0xff
lsl r0,8
add	r0,0xff
sub r0,r2
strh r0,r1
pop {r0-r2,pc}
.data
;r0=x
;r1=y
;r2=alpha
;r3=color
SetPixelAlpha:
push {r0-r7,LR}
lsl r0,1
lsl r5,r1,8
add r5,r0
ldr r0,=vScreenMem
add r5,r0
ldrh r0,r5
mov r1,r3
lsr r3,r0,11
lsr r6,r1,11
bl SetAlChanel
lsl r7,r6,11
lsl r3,r0,21
lsr r3,r3,27
lsl r6,r1,21
lsr r6,r6,27
bl SetAlChanel
lsl r4,r6,6
lsl r3,r0,27
lsr r3,r3,27
lsl r6,r1,27
lsr r6,r6,27
bl SetAlChanel
orr r6,r4
orr r6,r7
SetColor:
strh r6,r5
pop {r0-r7,PC}

SetAlChanel:
push {r4,lr}
mul r6,r2
mov r4,0x20
sub r4,r2
mul r3,r4
add r6,r3
lsr r6,5	
pop {r4,pc}

 

Функции рисования для новых агере (D830):

 

.arm
.align 2

;Рисует прямоугольник c альфа-каналом:
;r0=alpha+color
;r1=rect
myDrawAlphaRect:
	stmfd sp!,{r0-r7,lr}

	ldr r7,=_pIdcObjByHandle
	ldr r7,[r7]
	ldr r7,[r7+0x48]
	ldrh r6,[r1+6];Нижняя граница
	ldrh r5,[r1+4];Верхняя граница
	ldrh r4,[r1+2];Правая граница
	ldrh r3,[r1+0];Левая граница
;Шаг вертикали:
	mov r2,480
;Адаптация к буферу:
	mov r3,r3 lsl 1
	mov r4,r4 lsl 1
	mul r5,r5,r2
	mul r6,r6,r2
	add r6,r6,r3
;Шаг вертикали (адаптированный):
	sub r2,r2,r4
	add r2,r2,r3

;Начинаем...
	add r5,r5,r7
	add r6,r6,r7
	add r4,r4,r5
	add r7,r3,r5

loopMyDrawRect:
	ldrh r1,[r7+0]
	bl getAlphaColor
	STRH R1,[R7],2
	cmp r7,r4
	blt loopMyDrawRect
	add r4,480
	add r7,r7,r2
	cmp r7,r6
	ble loopMyDrawRect

	ldmfd sp!,{r0-r7,lr}
	bx lr

;Вернет в R1 опрозрачненный цвет
;по R0(основной цвет) и R1(подложка).
;17-22 биты (от 0 до 32)
;R0 - уровень непрозрачности.
getAlphaColor:
	stmfd sp!,{r0,r2-r7}
	mov r7,r0 lsr 16;Коэффициент непрозрачности
	rsb r6,r7,32;Коэффициент прозрачности

;Выделяем синее
	and r4,r1,0x1f;Цвет подложки
	and r3,r0,0x1f;Цвет кисти
;склееваем по коэффициенту
;синий цвет:
	mul r4,r4,r6
	mul r3,r3,r7
	add r3,r3,r4
;Компенсация:
	mov r2,r3 lsr 5

;Выделяем зеленое
	and r4,r1,0x7E0
	and r3,r0,0x7E0;Цвет кисти
;Склееваем по коэффициенту
;зеленый цвет:
	mul r4,r4,r6
	mul r3,r3,r7
	add r3,r3,r4
;Компенсация:
	and r3,r3,0xFC00;Применяем маску для очищения лишних битов
	orr r2,r2,r3 lsr 5;orr r2,r2,r3 lsr 5

;Выделяем красное
	mov r4,r1 lsr 11;Цвет подложки
	mov r3,r0 lsr 11;Цвет кисти
;Склееваем по коэффициенту
;зеленый цвет:
	mul r4,r4,r6
	mul r3,r3,r7
	add r3,r3,r4
;Компенсация:
	and r3,r3,0x3E0;Применяем маску для очищения лишних битов
	orr r1,r2, r3 lsl 6

	ldmfd sp!,{r0,r2-r7}
	bx lr
.thumb

;Рисует "коробочку".
myDrawBox:
	push {r0-r7,lr}
	ldr r7=_pIdcObjByHandle
	ldr r7,[r7]
	ldr r7,[r7+0x48]

	ldrh r2,[r1];Левая граница
	ldrh r3,[r1+2];Правая граница
	ldrh r4,[r1+4];Верхняя граница
	ldrh r5,[r1+6];Нижняя граница
;Шаг по вертикали:
	mov r1,240
	lsl r1,1
;адаптация к буферу
	lsl r2,1
	lsl r3,1
	mul r4,r1
	mul r5,r1
	add r4,r7
	add r5,r7

	add r6,r4,r2
	add r4,r3
	add r7,r5,r3
	add r3,r5,r2
	mov r2,r6

;Горизонтальный цикл:
myDrawBoxLoop1:
	strh r0,[r2]
	strh r0,[r3]
	add r2,2
	add r3,2
	cmp r3,r7
	blt myDrawBoxLoop1
;Вертикальный цикл
myDrawBoxLoop2:
	strh r0,[r6]
	strh r0,[r4]
	add r6,r1
	add r4,r1
	cmp r4,r7
	blt myDrawBoxLoop2
	strh r0,[r4]

	pop {r0-r7,pc}

 

Трассировка

 

Код, добавляющий возможность трассировки для телефонов агере платформы (D830):

 

.equfile "Trace.h";кто не знает что это, тому можно это убрать :)

.equ TB			0x3016CA70;Буфер трассировки
.equ sprintf	0x204F106E;используется ф-ция с неограниченным числом параметров
.equ strcpy		0x204EFBA4;любой эквивалент
.equ strcat		0x204EFB3C;любой эквивалент
.equ strlen		0x204EFBBA;любой эквивалент
.equ p_GSMMalloc	0x0400010C
.equ p_GSMFree	0x04000110
.equ ATSendReplyByEG	0x2040FAF8;выводит строку R0 на порт UART0. Параметр R1 надо занулить.

/*
Как найти _sprintf, strcpy и strcat - ваши проблемы. Я изучал алгоритмы ф-ций (зная адрес одной из них).
Впринципе можно разобрать подходящий колбэк из прошивки от х140 и вашей и найти эти ф-ции.
TB тоже находится давольно легко (путем разбора какой-нибудь колбэк ф-ции, использующей трассировку).
Можно восспользоваться строками и функциям трассировки.
Для ATSendReplyByEG я предлагаю такой алгоритм. Найдите в прошивке строку "+LOGL:" (без кавычек).
Найдите где она используется. Сразу после adr на эту строку будет вызов ф-ции. Это и есть ATSendReplyByEG.
*/

;Свободный регион памяти. Я использую "мусор", которые разработчики так любезно оставили.
;Трассировка. R0=маска_вывода, R1..R3=значения_подстановки (необязательно).
;Используется буфер трассировки TB.
0x211010D8:
%myTrace:;если кто не знает, зачем тут '%', можно его не писать.
	push {r0-r7,lr}
	sub sp,8

	;Добавим к маске адрес вызова:
		;Выделим память:
			bl strlen
			add r0,4
			ldr r1,=p_GSMMalloc
			ldr r1,[r1]
			bl call_by_R1
			mov r6,r0			

		adr r1,="%X: ";Это для вывода LR (адреса вызова)
		bl strcpy

		mov r0,r6
		ldr r1,[sp+8]
		bl strcat

	;Подготовим строку:
		ldr r0,=TB
		mov r1,r6
		ldr r2,[sp+40];r2=LR
		ldr r3,[sp+12];r3=R1
		ldr r4,[sp+16];r4=R2
		str r4,[sp]	;[sp]=R2
		ldr r4,[sp+20];r4=R3
		str r4,[sp+4];[sp+4]=R3
		bl sprintf

	;Выведем в порт:
		mov r1,0
		ldr r0,=TB
		bl ATSendReplyByEG

		;Освободим память:
			ldr r1,=p_GSMFree
			ldr r1,[r1]
			mov r0,r6
			bl call_by_R1

	add sp,8
	pop {r0-r7,pc}
	.data

%trace:
	push {r0-r7,lr}
	sub sp,8		

	;Подготовим строку:
		str r3,[sp]
		mov r3,r2
		mov r2,r1
		mov r1,r0
		ldr r0,=TB
		bl sprintf

	;Выведем в порт:
		mov r1,0
		ldr r0,=TB
		bl ATSendReplyByEG

	add sp,8
	pop {r0-r7,pc}

call_by_R1:
	bx r1

 

Низкоуровневое

 

.arm
;Функция, защищающая от кэширования.
;R0=Address, R1=Size
unCache:
STMFD SP!,{R0,R1,LR};Сохраняем регистры

ADD R1,R0;Получаем конечный адрес

;Получаем адреса, кратные 32
;(размеру "линии" DCache)
BIC R0,R0,0x1F
BIC R1,R1,0x1F

;Очистка кэша данных (Data Cache, DCache):
CacheLoop:
;Очистка одной "линии" кэша:
	MCR	p15,0,R0,c7,c14,1
;Инкримент цикла:
	ADD R0,0x20;0x20 - размер "линии" кэша
;Сравнение с конечным адресом:
	CMP R0,R1
;Условие продолжения (меньше или равно):
	BLE CacheLoop

;Сброс ("дренаж") буфера записи:
MCR	p15,0,R0,c7,c10,4;drain write buffer
;Обновление буфера команд
MCR p15, 0, r0, c7, c5, 0; invalidate icache (Instruction Cache)

LDMFD SP!,{R0,R1,PC};Загружаем регистры
.thumb

 

Ну и так, по мелочи...

 

;Возвращает в r0 число из строкового Hex-представления. В r0 - адрес строки хекса.
parseHex:
push {r1-r3,lr}
mov r1,8;Длинна записи.
mov r3,r0
mov r0,0
parseHexLoop:
ldrb r2,[r3]
sub r2,'0'
bmi parseHexError
cmp r2,9
ble parseHexDecimal
sub r2,7
parseHexDecimal:
lsl r0,4
add r0,r2
add r3,1
sub r1,1
bne parseHexLoop
parseHexError:
pop {r1-r3,pc}

;Записывает в память по адресу r1 данные из строкового
;Hex-представления. В r0 - адрес данных, в R2 - длинна.
stringHex:
push {r0,r1,r6,r7,lr}
mov r7,r0
add r6,r1,r2
stringHexLoop:
mov r0,r7
bl parseHex
str r0,r1
add r7,8
add r1,4
cmp r1,r6
blt stringHexLoop
pop {r0,r1,r6,r7,pc}

;Возвращает индекс последнего символа из r1 в строке из r0.
;Если символ не найден, будет возвращено 0. Индексация с 1.
%getLastCharPos:
push {r2-r4,lr}
mov r2,r0
mov r0,0
mov r4,0
getLastCharLoop:
ldrb r3,[r2]
cmp r3,0
beq exitLastChar
add r4,1
add r2,1
cmp r3,r1
bne getLastCharLoop
mov r0,r4
b getLastCharLoop
exitLastChar:
pop {r2-r4,pc}

;Копирует строку из r1 в r0 длинной строго r2
;(+в конце дописывается 0). Регистры не меняются.

%mycpystr:
push {r0-r3,lr}
add r2,r0
loopMycpystr:
ldrb r3,[r1]
strb r3,[r0]
add r1,1
add r0,1
cmp r0,r2
blt loopMycpystr
mov r3,0
strb r3,[r0]
pop {r0-r3,pc}


;Конвертирует LeftUnicode в Ansi. Строка передается в R1, записывается по адресу R0.

%myLeftUnicodeToAnsi:
 push {r0-r3,lr}
 mov r3,0xff
loopLeftUnicodeToAnsi:	 
 ldrh r2,[r1]
 cmp r2,0xff
 ble oneByte
 and r2,r3
 add r2,0xB0
oneByte:
 strb r2,[r0]
 add r0,1
 add r1,2
 cmp r2,0
 bne loopLeftUnicodeToAnsi
 pop {r0-r3,pc}

 

Надеюсь, не утомил :shock:

А вообще-то лучше как-то это все оформить иначе, чтобы не у каждого автора были набросаны функции, а функции распределены по разделам и у каждой конкретной функции подписан автор.

  • Like 1

Силы кончались, Слабостей - море...

Разом рухнули все мои сны...

Только я - мимо радости, горя -

Только я продолжаю идти...

Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

А вообще-то лучше как-то это все оформить иначе, чтобы не у каждого автора были набросаны функции, а функции распределены по разделам и у каждой конкретной функции подписан автор.

 

Ну если еще ни кто не решился это оформить, то я могу взяться за это.... Только просьба выкладывать коды функций и макросов как Neo_2kX в первом и последующих постах...

 

* Прикрепляю эскиз приложения

 

Ну так что меня кто-нить заметит или нет???

Ответьте мне пожалуйста, браться ли мне за это??? :51:

61529-17-03-08)1205782218_thumb.gif

Изменено пользователем .AleXo
  • Like 1

Samsung SGH-X100 ----- > УМЕР!!!

Nokia 6131 + 1Gb MicroSD ------> ОТОБРАЛИ!!!

Samsung SGH-E800 ------> СНОВА В МОДЕ :)

Ссылка на комментарий
Поделиться на другие сайты

  • 1 год спустя...

На днях написал один тумбовый макрос для перехода по номеру - tCase8, для замены конструкций

CMP Rn, #0

BEQ ...

CMP Rn, #1

BEQ ...

CMP Rn, #2

BEQ ...

...

Макрос на 8 переходов (на 7 работает тоже), если нужно меньше - надо подправить число параметров в теле макроса.

Код, компилируемый из макроса, более оптимален и по объёму , и по скорости выполнения, та как преобразуется не к последовательным проверкам на совпадение, а на табличном переходе по номеру (ИДА нормально понимает такие переходы).

Вот, например, следующий исходный код:

 

subpr:	push	{r3-r7,lr}
	ldrb r0,[r0]
	tCase8 0,8,finish,l1,l2,l3,l4,l5,l6,l7,l8
l1:	 	mov r0,#0
	b	finish
l2:		mov r0,#1
	b	finish
l3:		mov r0,#2
	b	finish	
l4:		mov r0,#3
	b	finish
l5:		mov r0,#4
	b finish
l6:		mov r0,#5
	b	finish
l7:		mov r0,#6
	b	finish
l8:		mov r0,#7
finish:
	mov	r0,	#0
	pop	{r3-r7,pc}

 

Компилируется в следующее (снято с ИДЫ):

				PUSH	{R3-R7,LR}
			 LDRB	R0, [R0]
			 CMP	 R0, #8
			 BCS	 def_208492BE
			 ADR	 R7, jpt_208492BE
			 LDRB	R7, [R7,R0]
			 LSL	 R7, R7, #1
			 ADD	 PC, R7
; ---------------------------------------------------------------------------
jpt_208492BE	DCB 3				 ; DATA XREF: sub_208492B0+8o
			 DCB 5
			 DCB 7
			 DCB 9
			 DCB 0xB
			 DCB 0xD
			 DCB 0xF
			 DCB 0x11
; ---------------------------------------------------------------------------

case_0								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #0
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_1								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #1
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_2								; CODE XREF: sub_208492B0+Ej
			MOV	 R0, #2
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_3								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #3
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_4								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #4
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_5								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #5
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_6								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #6
			 B	   def_208492BE
; ---------------------------------------------------------------------------

case_7								; CODE XREF: sub_208492B0+Ej
			 MOV	 R0, #7

def_208492BE						  ; CODE XREF: sub_208492B0+6j
								; sub_208492B0+1Aj ...
			 MOV	 R0, #0
			 POP	 {R3-R7,PC}

Синтаксис макроса следующий:

tCase8 Reg, Num, DefCase, c0, c1, c2, c3, c4, c5, c6, c7

где:

Reg - номер регистра, содержащего номер перехода (0..6)

Num - число переходов (без дефолтного, т.е. аналога Case Else)

DefCase - метка для дефолтного перехода, когда значение Reg вне диапазона, аналог Case Else в высокоуровневых языках

с0..сn - метки для переходов по номеру

 

Макрос писан на Кейле, с использованием встроенного макроса IRP.

Макрос использует регистр R7, поэтому его нельзя использовать как параметр Reg

На мой взгляд, его применение в патчах, где нужно выбрать переход в зависимости от непрерывного ряда значений параметра, как, например, в патче CGSN, оптимально.

Собственно, сам макрос:

tCase8	macro Reg, Num, DefCase, c0, c1, c2, c3, c4, c5, c6, c7
	x	set	1
	dw	(0x2800 | (Reg<<8)) + (Num);cmp	Rn,	#im
	bcs		DefCase
	$if (($&3)!=0)
		x set x+1
	$endif
	dw	0xA700 + x		; ADR	R7,	jptable
	dw	0x5C3F | (Reg << 6);ldrb	R7,	[R7,Rn]
	lsl		R7,	R7,#1
	add		PC,	R7
	if (x=2)
		dw	0
	endif
	a	set	$
	IRP lbl, <c0,c1,c2,c3,c4,c5,c6,c7>
		db (((lbl-a)&0xFF)>>1) - (2 - x)
	endm
	if (($&1)!=0)
		db	0
	endif
	if (($&3)!=0)
		dw	0
	endif

endm

Ссылка на комментарий
Поделиться на другие сайты

На днях написал один тумбовый макрос для перехода по номеру - tCase8

 

BinEdit умеет это без макросов:

.case Rx, default, metka0, metka1, …. – переход по метке в зависимости от значения в регистре Rx. default – метка на которую будет сделан переход при превышении значением Rx количества меток. Для хранения смещения используется 2 байта. Длина переходов до 65535 байт

 

.caseb Rx, default, metka0, metka1, …. – переход по метке в зависимости от значения в регистре Rx. default – метка на которую будет сделан переход при превышении значением Rx количества меток. Для хранения смещения используется 1 байт. Длина переходов до 255 байт

  • Like 2
5073IA3.png
Ссылка на комментарий
Поделиться на другие сайты

Интересно, а во что он их компилит? есть пример кода?

Кусок кода с патча "Отображение текста" для Х700

...........................
	LDR	R1, =0x18FC0008+0x92
	LDRB	R0, [R1]
	.case r0 loc_108678EE case_0 case_1 case_2 case_3 case_4 case_5

case_0:
LDR	R0, =0x000003FD
B	loc_108678C4
case_1:
LDR	R0, =0x00000E87
B	loc_108678C4
case_2:
MOV	R0, 40			
B	loc_108678CA
case_3:
MOV	R0, 41			
B	loc_108678CA
case_4:
LDR	R0, =0x00000314
B	loc_108678C4
case_5:
LDR	R0, =0x00000E3B
B	loc_108678C4
loc_108678C4:	
	BL	0x109DE520
	B	loc_108678CE
loc_108678CA:	
	BL	lk_get_my_text
loc_108678CE:	
	STR 	R0, [R4]
	LDR 	R6, [R4]
	LDR	R1, =0x1834A098	
	MOV	R0, R7
	STRB	R0, [R1]
	MOV	R0, #0x0
	STRH	R0, [R1, #14]
	MOV	R0, #0x64
	STRH	R0, [R1, #16]
	MOV	R0, #0xB0
	STRH	R0, [R1, #18]
	MOV	R0, #0x19
	STRH	R0, [R1, #20]
	POP	{R4}
	LDR	R0, =0x116BAF3C+1		
	BX	R0
loc_108678EE:	
	LDR	R0, =0x116BAF54+1		
	BX	R0

Компилит как:

.....................
	LDR	R1, =0x18FC009A
	LDRB	R0, [R1]
	CMP	R0, #0x6
	BCS	loc_114D0E9A
	ADR	R3, =0x114D0E4C
	ADD	R3, R3, R0
	LDRH	R3, [R3, R0]
	LSL	R3, R3, #1
	ADD	PC, R3
	NOP	
	DCD	0x0006;B loc_114D0E58 ;при 0x0000
	DCD	0x0008;B loc_114D0E5C ;при 0x0001
	DCD	0x000A;B loc_114D0E60 ;при 0x0002
	DCD	0x000C;B loc_114D0E64 ;при 0x0003
	DCD	0x000E;B loc_114D0E68 ;при 0x0004
	DCD	0x0010;B loc_114D0E6C ;при 0x0005

	loc_114D0E58:; CASE 0x0000	
	LDR	R0, =0x000003FD
	B	loc_114D0E70

	loc_114D0E5C:; CASE 0x0001	
	LDR	R0, =0x00000E87
	B	loc_114D0E70

	loc_114D0E60:; CASE 0x0002	
	MOV	R0, #0x28
	B	loc_114D0E76

	loc_114D0E64:; CASE 0x0003	
	MOV	R0, #0x29
	B	loc_114D0E76

	loc_114D0E68:; CASE 0x0004	
	LDR	R0, =0x00000314
	B	loc_114D0E70

	loc_114D0E6C:; CASE 0x0005	
	LDR	R0, =0x00000E3B
	B	loc_114D0E70
loc_114D0E70:	
	BL	off_114D176C
	B	loc_114D0E7A
loc_114D0E76:	
	BL	off_114D1778
loc_114D0E7A:	
	STR 	R0, [R4]
	LDR 	R6, [R4]
	LDR	R1, =0x1834A098
	MOV	R0, R7
	STRB	R0, [R1]
	MOV	R0, #0x0
	STRH	R0, [R1, #14]
	MOV	R0, #0x64
	STRH	R0, [R1, #16]
	MOV	R0, #0xB0
	STRH	R0, [R1, #18]
	MOV	R0, #0x19
	STRH	R0, [R1, #20]
	POP	{R4}
	LDR	R0, =0x116BAF3D
	BX	R0
loc_114D0E9A:	
	LDR	R0, =0x116BAF55
	BX	R0

Пожертвования отправлять сюда R256859050930

Ссылка на комментарий
Поделиться на другие сайты

Компилит как:

.....................
	LDR	R1, =0x18FC009A
	LDRB	R0, [R1]
	CMP	R0, #0x6
	BCS	loc_114D0E9A
	ADR	R3, =0x114D0E4C
	ADD	R3, R3, R0
	LDRH	R3, [R3, R0]
	LSL	R3, R3, #1
	ADD	PC, R3
	NOP	
	DCD	0x0006;B loc_114D0E58;при 0x0000
	DCD	0x0008;B loc_114D0E5C;при 0x0001
	DCD	0x000A;B loc_114D0E60;при 0x0002
	DCD	0x000C;B loc_114D0E64;при 0x0003
	DCD	0x000E;B loc_114D0E68;при 0x0004
	DCD	0x0010;B loc_114D0E6C;при 0x0005
...

Да, табличный переход!

Ещё раз респект автору БинЕдита!

Ну что ж, значит, этот макрос будет полезен тем, кто пользуется другими компилерами...

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


×
×
  • Создать...