Оффтоп вопрос про "профессионально на ASM".
Объекты на ASM научился создавать?
Выделять память в HEAP?
А это зачем? Явно AVR-овский подход. Для ARM в этом нет никакого смысла и выигрыша.6 mov R10,#0 ;Константы.
7 mov R11,#1
Смог заменитьkisssko писал(а):А это зачем? Явно AVR-овский подход. Для ARM в этом нет никакого смысла и выигрыша.6 mov R10,#0 ;Константы.
7 mov R11,#1
Тут все ALU-команды в коде содержат 8 бит immediate-данных, и сдвиг для них.
Так что в командах можно сразу писать #1 или #0 - на размер кода не повлияет.
Код: Выделить всё
cmp R1, R11Код: Выделить всё
cmp R1, #1Код: Выделить всё
str R11, [R0]Да, так правильно. Тем более, что для старших регистров (r8-r12) генерится 32-битная команда (кроме некоторых команд).cmp R1, #1
Код: Выделить всё
ldr r1, [r0, #4]ОтсюдаInstructions encoded in 16 bit when using registers R0-R7
ADR Rd, <label> (range 0 to 1020)
<ADDS|SUBS|MOVS> Rd, #imm8
<ADDS|SUBS> Rd, Rn, #imm3
<ADDS|SUBS> Rd, Rn, Rm
<ADCS|ANDS|EORS|BICS|MVNS|ORRS|SBCS|UXTB|UXTH|MULS> Rd, Rm (MULS may be slower than MUL on some CPUs)
RSBS Rd, Rn, #0
<REV|REV16|REVSH> Rd, Rm
<ASRS|LSRS|LSLS> Rn, Rm, #imm5
CMP Rn, #imm8
<CMP|CMN|TST> Rn, Rm (Rm can be any register for CMP)
<LDM|STM> Rn!, <registers>
<LDR|STR>{H|B} Rt, [Rn{, #imm5}]
<LDR|STR>{H|B} Rt, [Rn, Rm ]
LDRS<H|B> Rt, [Rn, Rm]
LDR Rt, <label> (0-1020)
<PUSH|POP> <registers>
IT{x{y{z}}} <cond>
CB{N}Z Rn, <label> (range 0 to 126)
B<cond> <label> (range -256 to 254)
B <label> (range -2048 to 2046)
Instructions encoded in 16 bit using registers R0-R15
MOV Rd, Rm
ADD Rd, Rm
BLX Rm
BX Rm
Я так и не смог здесь найти ответа на свой вопрос, как заменить строкуkisssko писал(а):Да, так правильно. Тем более, что для старших регистров (r8-r12) генерится 32-битная команда (кроме некоторых команд).cmp R1, #1
Вообще, для ARM нет нужды хранить константы в регистрах. Если уж так хочется чем то занять регистры,
то лучше часто используемыми адресами переменных. В одном на несколько рядом лежащих переменных, и использовать смещения.Вот так возможности архитектуры будут использоваться более полно.Код: Выделить всё
ldr r1, [r0, #4]
А ещё вот:ОтсюдаInstructions encoded in 16 bit when using registers R0-R7
ADR Rd, <label> (range 0 to 1020)
<ADDS|SUBS|MOVS> Rd, #imm8
<ADDS|SUBS> Rd, Rn, #imm3
<ADDS|SUBS> Rd, Rn, Rm
<ADCS|ANDS|EORS|BICS|MVNS|ORRS|SBCS|UXTB|UXTH|MULS> Rd, Rm (MULS may be slower than MUL on some CPUs)
RSBS Rd, Rn, #0
<REV|REV16|REVSH> Rd, Rm
<ASRS|LSRS|LSLS> Rn, Rm, #imm5
CMP Rn, #imm8
<CMP|CMN|TST> Rn, Rm (Rm can be any register for CMP)
<LDM|STM> Rn!, <registers>
<LDR|STR>{H|B} Rt, [Rn{, #imm5}]
<LDR|STR>{H|B} Rt, [Rn, Rm ]
LDRS<H|B> Rt, [Rn, Rm]
LDR Rt, <label> (0-1020)
<PUSH|POP> <registers>
IT{x{y{z}}} <cond>
CB{N}Z Rn, <label> (range 0 to 126)
B<cond> <label> (range -256 to 254)
B <label> (range -2048 to 2046)
Instructions encoded in 16 bit using registers R0-R15
MOV Rd, Rm
ADD Rd, Rm
BLX Rm
BX Rm
Код: Выделить всё
STR R11, [R0]Тут не изменить ничего.Вадиматоричик писал(а): Я так и не смог здесь найти ответа на свой вопрос, как заменить строкуна что-то типа STR #1, [R0] (Эта конструкция не работает). Тут http://we.easyelectronics.ru/STM32/asm- ... chalo.html вообще пишут, что нужно держать константы в памяти.Код: Выделить всё
STR R11, [R0]
Код: Выделить всё
get stm32f10x.s ;Заголовочный файл. Код: Выделить всё
;Имена регистрам.--------------------------------------------------------------------------------------------------------------
Temp RN R0 ;Для мелких операций.
Pointer RN R1 ;Адресс (указатель).
Data RN R2 ;Важные данные.
One RN R11 ;1.Смотря какой ассембер. В GAS и Keil по разному. В Keil есть неплохой мануал.Вадиматоричик писал(а):Решил переписать свою библиотеку под монохромный экран с AVR на STM с нуля. Но столкнулся с проблемой иерархии файлов. Ни в одной статье-мануале не уделяется должного внимания подключению внешних файлов. Удалось лишь подключить файл с адресами регистров и бит.Код: Выделить всё
get stm32f10x.s ;Заголовочный файл.
GET or INCLUDE
ARM Compiler toolchain v5.02 for µVision Assembler Reference
Home > Directives Reference > GET or INCLUDE
GET or INCLUDE
The GET directive includes a file within the file being assembled. The included file is assembled at the location of the GET directive. INCLUDE is a synonym for GET.
Syntax
GET filename
where:
filename
is the name of the file to be included in the assembly. The assembler accepts pathnames in either UNIX or MS-DOS format.
Usage
GET is useful for including macro definitions, EQUs, and storage maps in an assembly. When assembly of the included file is complete, assembly continues at the line following the GET directive.
By default the assembler searches the current place for included files. The current place is the directory where the calling file is located. Use the -i assembler command line option to add directories to the search path. File names and directory names containing spaces must not be enclosed in double quotes ( " " ).
The included file can contain additional GET directives to include other files.
If the included file is in a different directory from the current place, this becomes the current place until the end of the included file. The previous current place is then restored.
GET cannot be used to include object files.
Examples
AREA Example, CODE, READONLY
GET file1.s ; includes file1 if it exists
; in the current place.
GET c:\project\file2.s ; includes file2
GET c:\Program files\file3.s ; space is permitted
See also
Reference
INCBIN
Nesting directives.
Copyright © 2011-2012 ARM. All rights reserved. ARM DUI 0588B
Non-Confidential ID062912
PDF version
Home > Directives Reference > GET or INCLUDE
Copyright © Keil, An ARM Company. All rights reserved
Нужно инклудить для каждого файла, как и в Си. Естественно, инклудитьВадиматоричик писал(а): А как например разбить программу? Не хочется скакать по огромному файлу исправляя пару строк модульного кода. И еще. Если я как-нибудь именую регистры в одном файле, то почему эти обозначения не работают в другом? Например:Код: Выделить всё
;Имена регистрам.-------------------------------------------------------------------------------------------------------------- Temp RN R0 ;Для мелких операций. Pointer RN R1 ;Адресс (указатель). Data RN R2 ;Важные данные. One RN R11 ;1.
Да, тяжело после AVR с их писанными левой ногой аляповатыми даташитами , где все в кучу свалено .Вадиматоричик писал(а): нашел официальный datasheet на камень, но столкнулся с серьезной проблемой. В родной документации не описано ни одного регистра! Что делать - даже не знаю...
Это тебе жЫрный минус. Бросить все из за такой ерунды - это не наш метод...Разбираться не стал, ибо надоело уже мучиться с такими мелочами,
А кто сказал, что я бросил? Не дождетесьdosikus писал(а):Это тебе жЫрный минус. Бросить все из за такой ерунды - это не наш метод...Разбираться не стал, ибо надоело уже мучиться с такими мелочами,
Чушь какая-то , к чему тут мерянье членами с разработчиками ? К тому же демоборды, те же дискаверины , сделаны для быстрого старта а не практического применения в каких либо проектах. К примеру на той же F4, F3 или VL дискаверине заняты нужные пины .Вадиматоричик писал(а): Недавно был на одном конкурсе и "умные люди" мне посоветовали больше не делать "основу своими руками", не "изобретать велосипед". Трудиться на идею, а не на реализацию. + бросить все попытки сделать все с нуля, а пользоваться готовыми отладочными наборами и готовыми модулями. "Думаешь, что люди, которые их делали тупее тебя и ты сможешь их превзойти?...".
Гы ... а свои симатики они тебе не навязывали ? Знакомые советы "прогромистов на мясорубках".Вадиматоричик писал(а):Судите сами, так сказала комиссия в лице разработчиков компании siemens в Москве.
Код: Выделить всё
Steck1 equ 0x20000000+0x101 ;Вершина стека. 0x2000 0000 - начало ОЗУ (СОЗУ).
;Выделяем 1-е 0x100 (256) байт + 1 (из книги).
AREA RESET, DATA, READONLY ;Пишим таблицу вектаров.
EXPORT __Vectors
__Vectors ;Описываем вектора.
DCD Steck1 ; Значение R13 (Указателя стека).
DCD Reset_Handler ; Адрес переход к основной программе (Вычесляется автоматически).
EXPORT Reset_Handler ;Далее действия при включении.
AREA |.text|, CODE, READONLY ;В памяти кода.
Reset_Handler
Lal B Lal ;Бесконечный цикл.
END
END
Код: Выделить всё
Steck1 equ 0x20000000+0x101 ;Вершина стека. 0x2000 0000 - начало ОЗУ (СОЗУ).
AHB1ENR equ 0x40023830 ;Адреса.
GPIOBEN equ 0x00000002
GPIOB_MODER equ 0x40020400
MODER13_01 equ 0x04000000
PORTB_ODR equ 0x40020414
ODR13 equ 0x00002000
AREA RESET, DATA, READONLY ;Пишим таблицу вектаров.
EXPORT __Vectors
__Vectors ;Описываем вектора.
DCD Steck1 ; Значение R13 (Указателя стека).
DCD Reset_Handler ; Адрес переход к основной программе (Вычесляется автоматически).
EXPORT Reset_Handler ;Далее действия при включении.
AREA |.text|, CODE, READONLY ;В памяти кода.
Reset_Handler
ldr R1, = AHB1ENR ;Включаем тактирование порта B.
ldr R0, = GPIOBEN
str R0, [R1]
ldr R1, = GPIOB_MODER ;Настраиваем пин.
ldr R0, = MODER13_01
str R0, [R1]
ldr R1, = PORTB_ODR
Z ldr R0, = ODR13
str R0, [R1] ;Включаем светодиод.
ldr R2, = Off_Led ;Метка возвращения из процедуры ожидания в выключение.
b Delay
Off_Led str R0, [R1]
ldr R2, = Z
Delay ;Задержка.
ldr R0, =0xFFFFF
D sub R0, 1
cmp R0, 0
bne D
bx R2
END
END
Даже нужно!Вадиматоричик писал(а):3. Можно ли входить в процедуру иначе, не так, как я?
Код: Выделить всё
main
push {r4, lr} @ стёк должен быть выровнен на 8.
movw r0, #1000
bl delay
mov r0, #0 @ код выхода
pop {r4, pc} @ Выход из main
delay
subs r0, #1
nop
bne delay @ loop
bx lr @ выход из delay