реклама на сайте
подробности

 
 
> поясните принцип действия, матчасть :)
Kail
сообщение Feb 3 2007, 21:18
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 3-08-06
Пользователь №: 19 285



Изучая доку на RealView ASM V. 3.0, решил углубить свои знания в асме и пописать на нем. И как обычно стали вылезать впросы, которые не приходят в голову, когда пишешь на С и все опции проекта, почти без изменений из Keil'a.
Вот код:
Код
    
    AREA Strcopy, CODE, READONLY
            ENTRY
start
            ldr        r1, =srcstr    ; Pointer o first string
            ldr        r0, =dststr    ; Pointer to second string
            ldr        r3, =45        ; load 45
            ldr        r4, =0x40000004; load addres of RAM
            str     r3, [r4]    ; store 45 in RAM
            bl         strcopy        ; Call subroutie to do copy
stop
            b        stop        ;    make loop
strcopy
            ldrb    r2, [r1], #1; load byte and update address
            strb    r2, [r0], #1; Store byte and update address
            cmp        r2, #0        ; check for zero terminator
            bne        strcopy        ; keep going if not
            mov        pc, lr        ; return

            AREA Strings, DATA, READWRITE
srcstr        DCB "First string - source",0
dststr        DCB "Seconf string - destination",0
            END


Вот листинг линкера
Код
  
    Strcopy                                  0x00000000   Section       56  source1.o(Strcopy)
    source1.s                                0x00000000   Number         0  source1.o ABSOLUTE
    Strings                                  0x40000000   Section       50  source1.o(Strings)
    srcstr                                   0x40000000   Data          22  source1.o(Strings)
    dststr                                   0x40000016   Data          28  source1.o(Strings)
................................................................................
.........................................
    Total RO  Size (Code + RO Data)                   56 (   0.05kB)
    Total RW  Size (RW Data + ZI Data)                52 (   0.05kB)
    Total ROM Size (Code + RO Data + RW Data)        108 (   0.11kB)


Вот вопрос: в процессе отадки в симуляторе кейла, гляжу на адреса ОЗУ, т.е. 0x40000000. А там ничего нету. И кстати часть кода, которая должна копировать строку не работает. Точнее срабатывает один раз, находит нуль и все! Специально написал ряд инструкций, чтобы записать число 45 в ОЗУ. Все работает, в окне просмотра памяти вижу записанное мной число! Как я понимаю Total ROM Size (Code + RO Data + RW Data) - размер образа программы, который будет размещен во флэш. А Total RO Size - та область памяти, которую непосредственно будет считывать процессор и последовательно выполнять комманды (не учитывая прыжков и проч.). Но вот никак не могу понять как Total RW Size перебертся из Total ROM Size в ОЗУ, где ей и место. И почему вобще код копировани строки не работает???

Не хватает мне знания курса "Архиктура ЭВМ", который читают на специальностях, связанных с программированием. Всегда осовные вопросы возникают на грани взаимодействия памяти и процессора. Почему alligment, почему разные инструкции могут работать только с разными данными и проч. Приходится информацию доставать по крупицам, причем под x86. А потом додудывать под arm.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
d__
сообщение Feb 5 2007, 14:28
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 197
Регистрация: 26-08-04
Пользователь №: 548



Стоило ли так расстраиваться. В программе не хватило 15 строчек, сличайте, сличайте...
Я программировал на ассемблере 8080 и пдп11 -- это песня! Когда пришлось перейти на ассемблер 8086, дого плевался и матюкался на него, думая что ничего горше него в своей карьере не придется использовать. Однако я ошибался -- есть еще более стукнутые по голове ассемблеры, это ассемблер АРМ Лтд...
AREA Strcopy, CODE, READONLY
ENTRY
export start
import |Load$$ER_RW$$Base|
import |Image$$ER_RW$$Base|
import |Image$$ER_RW$$Length|

start
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ldr r0,=|Load$$ER_RW$$Base|
ldr r1,=|Image$$ER_RW$$Base|
ldr r2,=|Image$$ER_RW$$Length|
ldr SP,=stacktop
initloop
ldrb r3,[r0],#1
strb r3,[r1],#1
subs r2,#1
bne initloop
;################################################################
ldr r1, =srcstr ; Pointer o first string
ldr r0, =dststr ; Pointer to second string
ldr r3, =45 ; load 45
ldr r4, =0x40000004; load addres of RAM
str r3, [r4] ; store 45 in RAM
bl strcopy ; Call subroutie to do copy
stop
b stop ; make loop
strcopy
ldrb r2, [r1], #1; load byte and update address
strb r2, [r0], #1; Store byte and update address
cmp r2, #0 ; check for zero terminator
bne strcopy ; keep going if not
mov pc, lr ; return

AREA Strings, DATA, READWRITE
srcstr DCB "First string - source",0
dststr DCB "Seconf string - destination",0
AREA Stack,DATA,NOINIT,ALIGN=4
SPACE 32*4
stacktop
END
--------------------------------------------------------------------------
командная строчка линкера:
*.o --ro-base 0x00000000 --entry 0x00000000 --rw-base 0x40000000 --strict
--first start --map --xref --callgraph --symbols
--info sizes --info totals --info unused --info veneers
--list ".\strcpy.map"
-o "strcpy.axf"
Go to the top of the page
 
+Quote Post
Kail
сообщение Feb 5 2007, 16:33
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 3-08-06
Пользователь №: 19 285



Цитата(d__ @ Feb 5 2007, 14:28) *
export start
import |Load$$ER_RW$$Base|
import |Image$$ER_RW$$Base|
import |Image$$ER_RW$$Length|


Откуда Load$$ER_RW$$Base и проч. берутся. Глобальная метка линкера? Тогда помимо этого кода еще
скрипт для линкера нужен как бы...

Цитата(d__ @ Feb 5 2007, 14:28) *
ldr r0,=|Load$$ER_RW$$Base|
ldr r1,=|Image$$ER_RW$$Base|
ldr r2,=|Image$$ER_RW$$Length|
ldr SP,=stacktop
initloop
ldrb r3,[r0],#1
strb r3,[r1],#1
subs r2,#1
bne initloop

Как я понимаю это и есть копирование данных из ROM в RAM.
Цитата(d__ @ Feb 5 2007, 14:28) *
AREA Stack,DATA,NOINIT,ALIGN=4
SPACE 32*4
stacktop

Зачем стек? Он ведь не используется?


А вод еще задачка для самых сообразительных:
Глазеем на стартовый код под гнутый ассемблер:

/* copy .data section (Copy from ROM to RAM) */
ldr R1, =_etext
ldr R2, =_data
ldr R3, =_edata
1: cmp R2, R3
ldrlo R0, [R1], #4
strlo R0, [R2], #4
blo 1b

/* Clear .bss section (Zero init) */
mov R0, #0
ldr R1, =_bss_start
ldr R2, =_bss_end
2: cmp R1, R2
strlo R0, [R1], #4
blo 2b

Все чики-пики. Нативно понятно.
Теперь берм листиннг стартового кода под RealView (см. вложение). Где аналог?????? Где там хоть что-то похожее на копирование данных из RAM в ROM???? Я уже весь монитор взглядом испепелил, так и не понял. Нда буду продолжать шуршать мануалами, может что-то прояснится... Хотя подсказка мне бы очень помогла.
P. S. Недавно как раз читал про ПДП-11. Сурьезный агрегат. Хардкор.
P. S. S. Непонятно как тут делать вложения. В общем сознательная часть листинга стартового кода для Realview:
; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size


; Enter the C code

IMPORT __main
LDR R0, =__main
BX R0


; User Initial Stack & Heap
AREA |.text|, CODE, READONLY

IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap

LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR

Хде???? Хде оно, копроварие кода?

Сообщение отредактировал Kail - Feb 5 2007, 16:39
Go to the top of the page
 
+Quote Post
ek74
сообщение Feb 5 2007, 18:06
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 4-08-05
Из: г. Саратов
Пользователь №: 7 351



Цитата(Kail @ Feb 5 2007, 16:33) *
; Enter the C code

IMPORT __main
LDR R0, =__main
BX R0
Хде???? Хде оно, копроварие кода?

У Realview __main не тоже самое, что int main(void). Вот выдержка из "RealView Compilation Tools Version 3.0 for μVision Compiler and Libraries Guide":
Код
The entry point of a program is at __main in the C library where library code does the following:
1. Copies nonroot (RO and RW) execution regions from their load addresses to their execution addresses. Also, if any data sections are compressed, they are decompressed from the load address to the execution address. See RealView Compilation Tools v3.0 Linker and Utilities Guide for more details.
2. Zeroes ZI regions.
3. Branches to __rt_entry.

и далее
Код
The library function __rt_entry() runs the program as follows:
1. Calls __rt_stackheap_init() to set up the stack and heap.
2. Calls __rt_lib_init() to initialize referenced library functions, initialize the locale and, if necessary, set up argc and argv for main(). For C++, calls the constructors for any top-level objects by way of __cpp_initialize__aeabi_. See C++ initialization, construction, and destruction
on page 5-32 for more details.
3. Calls main(), the user-level root of the application. From main(), your program might call, among other things, library functions. See Library functions called from main() on page 5-35 for more information.
4. Calls exit() with the value returned by main().

Т.е. мы имеем последовательность вызовов startup -> __main -> __rt_entry -> main, по ходу которой и происходит инициализация кучи, стека, библиотек и областей памяти.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 20:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01423 секунд с 7
ELECTRONIX ©2004-2016