Гость do_not_know_Linux 17 декабря, 2021 Опубликовано 17 декабря, 2021 · Жалоба Здравствуйте уважаемые форумчане. Помогите пожаулуйста разобраться почему не работает эта инструкция она должна была поместить в регистр 11110001101000000000010100000111 r3, #7 условие в cond я вроде указал что должна выполняться всегда. Opration Code для mov 1101 но что -то не так. Кто понимает в этом объясните Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 17 декабря, 2021 Опубликовано 17 декабря, 2021 · Жалоба Изучение "потрохов" дело почтенное и всецело приветствуемое, но без фанатизма, ибо 32-битная архитектура не самый простой объект для побитного "раскуривания": не выпендривайтесь ;-), натравите ассемблер (думать должен человек, а "молотить" - машина) на MOV R3, #7 и посмотрите в его листинг (наверняка вы в единичках-ноликах накосячили или с нечётного адреса их расположили ;-)); тем более Thumb2 вне рамок команды IT не предусматривает условное выполнение команд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость do_not_know_Linux 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 45 minutes ago, Obam said: Изучение "потрохов" дело почтенное и всецело приветствуемое, но без фанатизма, ибо 32-битная архитектура не самый простой объект для побитного "раскуривания": не выпендривайтесь ;-), натравите ассемблер (думать должен человек, а "молотить" - машина) на MOV R3, #7 и посмотрите в его листинг (наверняка вы в единичках-ноликах накосячили или с нечётного адреса их расположили ;-)); тем более Thumb2 вне рамок команды IT не предусматривает условное выполнение команд. да вы правильно говорите. только это не выпендреж. я столкнулся с тем что плохо понимаю отличие от mov r3, #7 ldr r3, =7 решил немного изучить команды. только arm-none-eabi-objdump нагло врет. 50 minutes ago, Obam said: не предусматривает условное выполнение команд. а вот это я упустил из внимания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба В первом случае, второй аргумент (не более 8 бит) содержится в самой команде (самое быстрое и дешёвое исполнение), а во втором случае второй аргумент будет выбран из памяти с использованием счетчика команд как базового регистра. А вообще, вам же рекомендовали книжки Джозефа Ю - они лучше любого форума ;-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость do_not_know_Linux 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 4 hours ago, Obam said: лучше любого форума скажите еще пожалуйста если несложно. я к примеру пишу mov r3, r7 но после компиляции это заменяется на add r3, r7 #0 есть ли какие способы заставить компилятор строго исполнять инструкции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба Нет. Писать на ассемблере значит нужно, чтобы не заменял ничего. А еще есть такая штука как оптимизатор, и он может порождать такой поток инструкций, которого в Вашем коде явно и близко не было. Простой пример void cUARTDMARx::initUART() { #define UART_BAUDRATE 921600 const sHwCfgTbl *const cfg = &HwCfgTbl[static_cast<u32>(hwCfgNum)]; ... #define BRTOFIX(apbfreq, br) divrnd((u64)(apbfreq) << 3, (br) * 8) #define BRRCALC(apbfreq, br) (BRTOFIX(apbfreq, br) >> 3 << 4 | \ (BRTOFIX(apbfreq, br) & 0x7)) const u32 brrAPB1 = BRRCALC(42000000, UART_BAUDRATE), brrAPB2 = BRRCALC(84000000, UART_BAUDRATE); cfg->uart.hw->BRR = cfg->uart.hw == USART1 || cfg->uart.hw == USART6 ? brrAPB2 : brrAPB1; ... } Строчка cfg->uart.hw->BRR = cfg->uart.hw == USART1 || cfg->uart.hw == USART6 ? brrAPB2 : brrAPB1; превратилась в 0x0800058E F0200203 BIC r2, r0, #0x03 0x08000592 2A0C CMP r2, #0x0C 0x08000594 BF08 IT EQ 0x08000596 23B3 MOVEQ r3, #0xB3 0x08000598 2804 CMP r0, #0x04 0x0800059A BF38 IT CC 0x0800059C 23B3 MOVCC r3, #0xB3 0x0800059E 608B STR r3, [r1, #0x08] Т.е. нет никакого сравнения cfg->uart.hw с адресами USART1/6. Вместо этого умный оптимизатор проследил, как hwCfgNum влияет на то, будет ли в cfg->uart.hw USART1/6 или же что-то другое, и на основе этой информации использовал в качестве операнда именно константу hwCfgNum. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 9 hours ago, do_not_know_Linux said: да вы правильно говорите. только это не выпендреж. я столкнулся с тем что плохо понимаю отличие от mov r3, #7 ldr r3, =7 решил немного изучить команды. только arm-none-eabi-objdump нагло врет. Ничего он не врет ))) Вы делаете ассемблерные вставки в С файле или пишите на ассемблере прямо в .s файле ? Вот попробовал у себя в .s файле вашу конструкцию ldr r0, =7 ldr r0, =7000000 mov r1, r0 mov r0, #7 Вот что выдает листинг после компиляции // address opcode mnnemonic ldr r0, =7 1a00c708: f04f 0007 mov.w r0, #7 ldr r0, =7000000 1a00c70c: 4809 ldr r0, [pc, #36] ; (1a00c734 <LoopForever+0x20>) mov r1, r0 1a00c70e: 4601 mov r1, r0 mov r0, #7 1a00c710: f04f 0007 mov.w r0, #7 ..... ..... 1a00c734: 006acfc0 .word 0x006acfc0 Компилятор GCC. Cortex-M3 Address, Opcode - в шестнадцатеричной системе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 5 часов назад, do_not_know_Linux сказал: но после компиляции это заменяется на add r3, r7 #0 есть ли какие способы заставить компилятор строго исполнять инструкции? И что? Какая разница? Это одно и то же. Вы заглядывали в систему команд? Вполне допускаю, что MOV R3, R7 на уровне опкода как раз и кодируется как ADD R3, R7, #0. Поэтому дизассемблер в принципе не сможет определить, что было у вас в исходнике. С таким же успехом транслятор мог MOV R3, R7 транслировать в SUB R3, R7, #0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 2 часа назад, Arlleex сказал: Нет. Писать на ассемблере значит нужно, чтобы не заменял ничего. И тем не менее, если IAR-у написать: MOV32 R1, #45678h то хоть такой инструкции и нет, он вполне успешно сгенерит код. Конечно, это потому что MOV32 - встроенный макрос (сгенерящий пару инструкций: MOV R1, #5678h; MOVT R1, #4) Но в листинге это выглядит как результат трансляции одной инструкции: 0000003E 45F27861C0F20 MOV32 R1, #45678h 401 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость do_not_know_Linux 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 1 hour ago, jcxz said: И что? Какая разница? Это одно и то же. знаете, я могу мешать суп лошкой, поварежкой и вилкой. действие вроде одно и тоже но это не одно и тоже. и mov r3, r7 add r3, r7 #0 дают один и тот же разультат, но это не одно и то же. 1 hour ago, jcxz said: Вы заглядывали в систему команд? пытаюсь. 4 hours ago, Arlleex said: Нет. Писать на ассемблере значит нужно, чтобы не заменял ничего. А еще есть такая штука как оптимизатор, и он может порождать такой поток инструкций, которого в Вашем коде явно и близко не было. Простой пример void cUARTDMARx::initUART() { #define UART_BAUDRATE 921600 const sHwCfgTbl *const cfg = &HwCfgTbl[static_cast<u32>(hwCfgNum)]; ... #define BRTOFIX(apbfreq, br) divrnd((u64)(apbfreq) << 3, (br) * 8) #define BRRCALC(apbfreq, br) (BRTOFIX(apbfreq, br) >> 3 << 4 | \ (BRTOFIX(apbfreq, br) & 0x7)) const u32 brrAPB1 = BRRCALC(42000000, UART_BAUDRATE), brrAPB2 = BRRCALC(84000000, UART_BAUDRATE); cfg->uart.hw->BRR = cfg->uart.hw == USART1 || cfg->uart.hw == USART6 ? brrAPB2 : brrAPB1; ... } Строчка cfg->uart.hw->BRR = cfg->uart.hw == USART1 || cfg->uart.hw == USART6 ? brrAPB2 : brrAPB1; превратилась в 0x0800058E F0200203 BIC r2, r0, #0x03 0x08000592 2A0C CMP r2, #0x0C 0x08000594 BF08 IT EQ 0x08000596 23B3 MOVEQ r3, #0xB3 0x08000598 2804 CMP r0, #0x04 0x0800059A BF38 IT CC 0x0800059C 23B3 MOVCC r3, #0xB3 0x0800059E 608B STR r3, [r1, #0x08] Т.е. нет никакого сравнения cfg->uart.hw с адресами USART1/6. Вместо этого умный оптимизатор проследил, как hwCfgNum влияет на то, будет ли в cfg->uart.hw USART1/6 или же что-то другое, и на основе этой информации использовал в качестве операнда именно константу hwCfgNum. я вижу что вы единственный понимаете сейчас о чем речь. помогите пожалуйста советом, скажите есть ли какие-нибудь способы заставить компилятор arm-none-eabi не трогать мой код и оставить его в таком виде в котором я его написал ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 21 minutes ago, do_not_know_Linux said: mov r3, r7 add r3, r7 #0 скажите есть ли какие-нибудь способы заставить компилятор arm-none-eabi не трогать мой код и оставить его в таком виде в котором я его написал ? Я же выше привел вам пример того, что ассемблер GCC не заменяет mov на add Покажите как вы запускается компиляцию вашего файла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 1 час назад, jcxz сказал: И тем не менее, если IAR-у написать... Это я понимаю. Просто у того же ассемблера есть устоявшиеся нотации. И в этих нотациях допустимы псевдокоманды, которые могут иметь контекстно-зависимый бинарный вид. Те же LDR R0, =XXX - это есть псевдокоманда, и реально она превратится во что угодно, что компилятору будет наиболее контекстно подходящим. Зато это трындец как удобно, т.к. не нужно держать в голове все эти ограничения на смещения адресов, области допустимых значений и т.д., к тому же многие пулы констант автоматом создаются "недалеко" от места использования для загрузки данных относительно PC. 30 минут назад, do_not_know_Linux сказал: ...есть ли какие-нибудь способы заставить компилятор arm-none-eabi не трогать мой код... Я таких способов, к сожалению, не знаю. Более того, выше правильно заметили, что некоторые ассемблерные мнемоники могут иметь одно и то же бинарное представление. Например, в том же AVR команда очистки регистра CLR R5 окажется полностью бинарно-идентична команде EOR R5, R5. В Cortex-ах такие команды тоже есть. P.S. И, пожалуйста, не цитируйте весь объем сообщений - в глазах разъезжаются объемные посты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 45 минут назад, do_not_know_Linux сказал: дают один и тот же разультат, но это не одно и то же. Если не дошло, повторю ещё раз: загляните в систему команд CM3. У CM3 "MOV R3, R7" и "ADD R3, R7, #0" - это одна и та же команда. И CM3 просто не имеет отдельного опкода для "MOV R3, R7", потому как нафиг не нужно. 26 минут назад, dimka76 сказал: Я же выше привел вам пример того, что ассемблер GCC не заменяет mov на add Он не заменяет, он просто вместо ADD, пишет MOV когда константа ==0. Откройте систему команд и попробуйте найти там команду MOV Rx, Ry. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость do_not_know_Linux 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 45 minutes ago, dimka76 said: же выше привел вам пример того, что ассемблер GCC не заменяет mov на add у меня заменяет... 29 minutes ago, Arlleex said: пожалуйста, не цитируйте весь объем сообщений да так получилось. не специально. 28 minutes ago, jcxz said: Если не дошло, повторю ещё раз: загляните в систему команд CM3. Киньте пожалуйста ссылку на описание инструкциий в которую мне нужно заглянуть, чтобы понять что add r3, r7, #0 и mov r3, r7 это одна и таже команда. просто я вот вижу(мне кажется) что у них опкоды у mov и add отличаются. Я не ни в коем случае не оспариваю сказаное вами просто хочу разобраться с тем что мне кажется. Прошу уважаемых форумчан понять правильно и не злится. 1 hour ago, dimka76 said: как вы запускается компиляцию вашего файла arm-none-eabi-as myFile.s Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 18 декабря, 2021 Опубликовано 18 декабря, 2021 · Жалоба 2 hours ago, jcxz said: Если не дошло, повторю ещё раз: загляните в систему команд CM3. У CM3 "MOV R3, R7" и "ADD R3, R7, #0" - это одна и та же команда. И CM3 просто не имеет отдельного опкода для "MOV R3, R7", потому как нафиг не нужно. Разве ? 1 hour ago, do_not_know_Linux said: у меня заменяет... arm-none-eabi-as myFile.s make all arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release) Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. mkdir -p release release/obj release/dep release/lst Assembling: startup_lpc18xx.s arm-none-eabi-as -c -mcpu=cortex-m3 -mthumb -gdwarf-2 -I./ -I. -amhlds=release/lst/startup_lpc18xx.lst startup_lpc18xx.s -o release/obj/startup_lpc18xx.o Linking: release/tst_asm__CM3.elf arm-none-eabi-gcc release/obj/startup_lpc18xx.o -mcpu=cortex-m3 -mthumb -lm -nostartfiles -TLPC1833_flash.ld -Wl,-Map=release/lst/tst_asm__CM3.map,--cref -Wl,--gc-sections -o release/tst_asm__CM3.elf arm-none-eabi-objdump -h -S -C release/tst_asm__CM3.elf > release/lst/tst_asm__CM3.lss arm-none-eabi-objcopy -O ihex release/tst_asm__CM3.elf release/tst_asm__CM3.hex arm-none-eabi-objcopy -O binary release/tst_asm__CM3.elf release/tst_asm__CM3.bin Size: text data bss dec hex filename 394 0 0 394 18a release/obj/startup_lpc18xx.o 384 0 3072 3456 d80 release/tst_asm__CM3.elf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться