Kail 0 3 февраля, 2007 Опубликовано 3 февраля, 2007 · Жалоба Изучая доку на 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 4 февраля, 2007 Опубликовано 4 февраля, 2007 · Жалоба Это весь ваш код? Стандартного Startup.s нет? Библиотечная __main вызывается? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 4 февраля, 2007 Опубликовано 4 февраля, 2007 · Жалоба А в твоей системе реально существует RAM по адресу 0x40000000? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kail 0 4 февраля, 2007 Опубликовано 4 февраля, 2007 · Жалоба А кто по вашему выполняет стартовый код? Тот же процессор, и в функцию main входить вполне не обязательно. может я вообще харкорный прогер и пишу все на чистом асме. Код этот почти целиком из мануала на armar. Код линкуется под LPC2106, озу по адресу 0x40000000. И есть кусок кода, который я специально втсавил сам, чтобы проверить работу с памятью. Число 45 записывается по адресу 0x40000004. После выполнения этого участка, вижу в памяти записанное число. Причем, если адрес в сырце ввести другой, например 0x300000000, Симулятор вполне обоснованно ругается на ошибкудоступа памяти, ибо ОЗУ там нету. Такое у меня ощющение, что код представленный в мануале, просто не рабочий. Ведь DCD только лишь резервирует место в ОЗУ, но ничего туда не записывает. Необходимо еще вставить код, который перепишет из ROM строки в RAM, а потом уже запускать копирование строк. Вообще-то стыд и позор для arm писать мануалы с неработающим кодом, может я все-таки не прав и чего-то недопонмаю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 · Жалоба Такое у меня ощющение, что код представленный в мануале, просто не рабочий. Ведь DCD только лишь резервирует место в ОЗУ, но ничего туда не записывает. Необходимо еще вставить код, который перепишет из ROM строки в RAM, а потом уже запускать копирование строк. Вообще-то стыд и позор для arm писать мануалы с неработающим кодом, может я все-таки не прав и чего-то недопонмаю? для компилятора СИ есть несколько сегментов памяти. один из них должен быть обнулён перед запуском основной программы, другой должен быть заполнен уже заранее заданным содержимым (скопирован из ПЗУ в ОЗУ). Вот как раз эти инициализирующие действия и выполняет sturtup. Поэтому DCD как раз инициализирует ячейку, только в ПЗУ, которую потом надо будет скопировать ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kail 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 · Жалоба для компилятора СИ есть несколько сегментов памяти. один из них должен быть обнулён перед запуском основной программы, другой должен быть заполнен уже заранее заданным содержимым (скопирован из ПЗУ в ОЗУ). Вот как раз эти инициализирующие действия и выполняет sturtup. Поэтому DCD как раз инициализирует ячейку, только в ПЗУ, которую потом надо будет скопировать ОЗУ. Но я ведь не использую компилятор СИ. Все на ассемблере написано. А вообще, я разобрался, спасибо. Asm - рулит полюбас! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
d__ 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 · Жалоба Стоило ли так расстраиваться. В программе не хватило 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" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kail 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 (изменено) · Жалоба 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 Хде???? Хде оно, копроварие кода? Изменено 5 февраля, 2007 пользователем Kail Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
d__ 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 · Жалоба Возьми доку на линкер и запусти поиск по тексту с параметрои одной из этих меток, например Load$$ER_RW$$Base, там все написано... Инициализация так называемого RTL у ИАРА и РВ спрятана в либах и относится к исполняемой системе языка Ц. Если ты пишешь прогу на чистом ассемблере инициализацию ртл должен делать ручками или выдернуть соотв субрутины из либы, но там очень много лишнего. И по моему есть сурцы этих субр, только не помню где... Зачем стек? Он ведь не используется? Это так наз "правила хорошого тона " при программировании на ассемблере. Правильно, у тебя используется только один уровень вложения подпрограмм, но если не дай Бог уровень вложения больше одного, тебя постигнет краш. Поэтому, это та сама соломка подстеленная на случай падения... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ek74 0 5 февраля, 2007 Опубликовано 5 февраля, 2007 · Жалоба ; 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, по ходу которой и происходит инициализация кучи, стека, библиотек и областей памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться