Перейти к содержанию
    

поясните принцип действия

Изучая доку на 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.

Поделиться сообщением


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

Это весь ваш код?

Стандартного Startup.s нет?

 

Библиотечная __main вызывается?

Поделиться сообщением


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

А кто по вашему выполняет стартовый код? Тот же процессор, и в функцию main входить вполне не обязательно. может я вообще харкорный прогер и пишу все на чистом асме. Код этот почти целиком из мануала на armar. Код линкуется под LPC2106, озу по адресу 0x40000000. И есть кусок кода, который я специально втсавил сам, чтобы проверить работу с памятью. Число 45 записывается по адресу 0x40000004. После выполнения этого участка, вижу в памяти записанное число. Причем, если адрес в сырце ввести другой, например 0x300000000, Симулятор вполне обоснованно ругается на ошибкудоступа памяти, ибо ОЗУ там нету.

Такое у меня ощющение, что код представленный в мануале, просто не рабочий. Ведь DCD только лишь резервирует место в ОЗУ, но ничего туда не записывает. Необходимо еще вставить код, который перепишет из ROM строки в RAM, а потом уже запускать копирование строк. Вообще-то стыд и позор для arm писать мануалы с неработающим кодом, может я все-таки не прав и чего-то недопонмаю?

Поделиться сообщением


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

Такое у меня ощющение, что код представленный в мануале, просто не рабочий. Ведь DCD только лишь резервирует место в ОЗУ, но ничего туда не записывает. Необходимо еще вставить код, который перепишет из ROM строки в RAM, а потом уже запускать копирование строк. Вообще-то стыд и позор для arm писать мануалы с неработающим кодом, может я все-таки не прав и чего-то недопонмаю?

для компилятора СИ есть несколько сегментов памяти. один из них должен быть обнулён перед запуском основной программы, другой должен быть заполнен уже заранее заданным содержимым (скопирован из ПЗУ в ОЗУ). Вот как раз эти инициализирующие действия и выполняет sturtup. Поэтому DCD как раз инициализирует ячейку, только в ПЗУ, которую потом надо будет скопировать ОЗУ.

Поделиться сообщением


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

для компилятора СИ есть несколько сегментов памяти. один из них должен быть обнулён перед запуском основной программы, другой должен быть заполнен уже заранее заданным содержимым (скопирован из ПЗУ в ОЗУ). Вот как раз эти инициализирующие действия и выполняет sturtup. Поэтому DCD как раз инициализирует ячейку, только в ПЗУ, которую потом надо будет скопировать ОЗУ.

 

Но я ведь не использую компилятор СИ. Все на ассемблере написано. А вообще, я разобрался, спасибо.

Asm - рулит полюбас!

Поделиться сообщением


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

Стоило ли так расстраиваться. В программе не хватило 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"

Поделиться сообщением


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

export start

import |Load$$ER_RW$$Base|

import |Image$$ER_RW$$Base|

import |Image$$ER_RW$$Length|

 

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

скрипт для линкера нужен как бы...

 

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.

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

Поделиться сообщением


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

Возьми доку на линкер и запусти поиск по тексту с параметрои одной из этих меток, например Load$$ER_RW$$Base, там все написано... Инициализация так называемого RTL у ИАРА и РВ спрятана в либах и относится к исполняемой системе языка Ц. Если ты пишешь прогу на чистом ассемблере инициализацию ртл должен делать ручками или выдернуть соотв субрутины из либы, но там очень много лишнего. И по моему есть сурцы этих субр, только не помню где...

 

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

 

Это так наз "правила хорошого тона " при программировании на ассемблере. Правильно, у тебя используется только один уровень вложения подпрограмм, но если не дай Бог уровень вложения больше одного, тебя постигнет краш. Поэтому, это та сама соломка подстеленная на случай падения...

Поделиться сообщением


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

; 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, по ходу которой и происходит инициализация кучи, стека, библиотек и областей памяти.

Поделиться сообщением


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

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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