
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.60] |
![]() |
|
Страницы: (81) « Первая ... 78 79 [80] 81 ( Перейти к последнему сообщению ) |
Сообщ.
#1186
,
|
|
|
Наткнулся на описание функции из книжки AMD (BIOS and Kernel Developer’s Guide for the AMD Athlon™ 64 and AMD Opteron™ Processors):
![]() ![]() (int,int,int) TranslateSysAddrToCS((uint32)SystemAddr){ int CSFound, NodeID, CS, F1Offset, F2Offset, Ilog; uint32 IntlvEn, IntlvSel; uint32 DramBase, DramLimit, DramEn; uint32 HoleOffset, HoleEn; uint32 CSBase, CSLimit, CSMask, CSEn; uint32 InputAddr, Temp; CSFound = 0; for(NodeID = 0; NodeID < 8; NodeID++){ F1Offset = 0x40 + (NodeID << 3); DramBase = Get_PCI(bus0, dev24 + NodeID, func1, F1Offset); DramEn = DramBase & 0x00000003; IntlvEn = (DramBase & 0x00000700) >> 8; DramBase = DramBase & 0xFFFF0000; ... if(CSFound) break; } return(CSFound,NodeID,CS); } Снова простая попытка/схема реализовать столь нужный функционал! А то вечно приходится "костыли" городить, чтобы вернуть два-три значения... Эх... ![]() |
Сообщ.
#1187
,
|
|
|
Цитата Славян @ И простой вопрос: это же концептуальная запись (возврат нескольких значений)? Нет же такого ни в какой версии Си-компилятора? Это С-подобный псевдокод. Смотрится нагляднее, чем возвращать структуру. Но это невалидный С-код. Цитата Славян @ А то вечно приходится "костыли" городить, чтобы вернуть два-три значения... Эх... Да нет, структуры это решают красиво. Автор решил еще "приукрасить" ![]() |
![]() |
Сообщ.
#1188
,
|
|
В Плюсах есть, но синтаксис другой. Вроде того:
![]() ![]() std::tuple<int, int, int> TranslateSysAddrToCS(uint32_t SystemAddr){ /* ... */ return { CSFound, NodeID, CS }; } // int [found, node, cs] = TranslateSysAddrToCS(0x12345678u); |
Сообщ.
#1189
,
|
|
|
Цитата Qraizer @ В Плюсах есть, но синтаксис другой. Речь не о плюсах. В Си такое реализовать наиболее просто на структурах. |
Сообщ.
#1190
,
|
|
|
Сперва сдержался, но всеж не могу - уж очень хочется поёрничать, очень!
![]() В далеком 2011 году в Стандарте С++ появилась киллер-фича "лямбды". Сколько себя помню в Perl, а это примерно 1997 год, там всегда это было. Никогда такого не было, и вот опять!!! Сколько себя помню в Perl, а это примерно 1997 год, там всегда была возможность возврата множественного результата. Для С ... бида-пичаль, а для C++ ... ешьте std::tuple в 2025 году! ![]() Скрытый текст ![]() ![]() #!/usr/local/bin/perl use strict; use warnings; my ($sign, $int, $frac) = SuperDiv(3,-2); print "$sign$int.$frac\n"; sub SuperDiv { my ($dividend, $divisor) = @_; my $res = $dividend / $divisor; my $sign = ($res < 0) ? "-" : ""; my $int = int(abs($res)); my $frac = abs($res) - $int; $frac =~ s/^0\.//; return ($sign, $int, $frac); } ![]() ![]() -1.5 ![]() Это так, коротко о хороших и гениальных языках программирования! |
Сообщ.
#1191
,
|
|
|
Цитата Majestio @ В далеком 2011 году в Стандарте С++ появилась киллер-фича "лямбды". Сколько себя помню в Perl, а это примерно 1997 год, там всегда это было. В перл можно управлять захватом контекста лямбды? Можно определять, по значению, по ссылке или вообще перенести данные в лямбду? Вот и получается, что слово одно, а фичи разные ![]() Добавлено Цитата Majestio @ Для С ... бида-пичаль, а для C++ ... ешьте std::tuple в 2025 году! ![]() Скрытый текст ![]() ![]() #!/usr/local/bin/perl use strict; use warnings; my ($sign, $int, $frac) = SuperDiv(3,-2); print "$sign$int.$frac\n"; sub SuperDiv { my ($dividend, $divisor) = @_; my $res = $dividend / $divisor; my $sign = ($res < 0) ? "-" : ""; my $int = int(abs($res)); my $frac = abs($res) - $int; $frac =~ s/^0\.//; return ($sign, $int, $frac); } ![]() ![]() -1.5 ![]() Это так, коротко о хороших и гениальных языках программирования! tuple тоже в 11 появился (хотя были потом изменения). Кстати, это класс стандартной библиотеки, а не часть самого языка. Т.е. возможности языка позволяют реализовать подобное не включая в сам язык. Добавлено Цитата Majestio @ Никогда такого не было, и вот опять!!! Сколько себя помню в Perl, а это примерно 1997 год... Ну а чего perl? Чего там 97 год? Можно лисп вспомнить ![]() |
Сообщ.
#1192
,
|
|
|
Цитата D_KEY @ В перл можно управлять захватом контекста лямбды? Можно определять, по значению, по ссылке или вообще перенести данные в лямбду? По ссылке ![]() ![]() my $x = 10; my $f = sub { return $x++ }; $f->(); # изменяет $x По значению ![]() ![]() my $x = 10; my $f = do { my $copy = $x; # создаём локальную копию sub { return $copy++ } }; $f->(); # не изменяет $x Перенос ![]() ![]() my $x = 10; my $f = do { my $moved = $x; undef $x; # "обнуляем" внешнюю переменную sub { return ++$moved } }; $f->(); # переносит 10 в лямбду, а $x становится undef Цитата D_KEY @ Вот и получается, что слово одно, а фичи разные ![]() |
Сообщ.
#1193
,
|
|
|
Цитата D_KEY @ tuple тоже в 11 появился (хотя были потом изменения). Я знаю. Написал это к тому, что на дворе 2025 год, а до сих пор это неудобство. Например в Dart тоже формально нельзя возвращать более одного значения, но там допустима конструкция: ![]() ![]() (int, String) myfunc() { return (42, "hello"); } void main() { var (num, str) = myfunc(); // деструктуризация print("$num, $str"); } Функция myfunc по факту возвращает одно значение типа Record. Но посмотри как это красиво записано, и не нужно каких-либо библиотек. Без оверхеда лучше. |
![]() |
Сообщ.
#1194
,
|
|
К вопросу об оверхеде
![]() ![]() auto [found, node, cs] = TranslateSysAddrToCS(0x12345678u); ![]() ![]() mov edx, 305419896 ; 12345678H lea rcx, QWORD PTR $S1$[rsp] ;<- call ?TranslateSysAddrToCS@@YA?AV?$tuple@HHH@std@@I@Z ; TranslateSysAddrToCS ; Line 10 mov r8d, DWORD PTR $S1$[rsp] ;<- mov edx, DWORD PTR $S1$[rsp+4] ;<- mov ecx, DWORD PTR $S1$[rsp+8] ;<- ![]() ![]() std::tuple<int, int, int> TranslateSysAddrToCS(unsigned SystemAddr) { int CSFound = SystemAddr >> 16, NodeID = SystemAddr % (1 << 16), CS = SystemAddr != 0; /* ... */ return { CSFound, NodeID, CS }; } ![]() ![]() xor eax, eax movzx r8d, dx mov r9d, edx ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple ; Line 158 mov DWORD PTR [rcx+4], r8d ;<- ; File D:\Work\DelMe\qq.cpp ; Line 5 shr r9d, 16 test edx, edx ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple ; Line 158 mov DWORD PTR [rcx+8], r9d ;<- ; File D:\Work\DelMe\qq.cpp ; Line 5 setne al ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple ; Line 158 mov DWORD PTR [rcx], eax ;<- ; File D:\Work\DelMe\qq.cpp ; Line 7 mov rax, rcx ; Line 8 ret 0 |
Сообщ.
#1195
,
|
|
|
Цитата Qraizer @ Можно на Dart посмотреть? Такое я еще не пробовал. Дело в том, что Dart сперва копилирует свой код в промежуточный, а уже потом тулчейнами в код целевой платформы. Я пока баловался только для Web - а там целевой код javascript. В принципе могу собрать exe для винды, но как там найти нужные места в ассемблерном представлении - я х3. Хэлоу ворлд будет порядка 20 метров. Хотя консольное приложение должно быть поменьше, т.к. хэлоу ворлд я делал на Dart+Flutter. А там статически влинковывается весь графический движок. Добавлено ![]() Засада! Оказывается промежуточное представление на С++ делает не Dart, а Flutter для свои "обвязок". Код на Dart компилячится напрямую. Добавлено exe получается 5 мегов, а дизасемблирование 105 мегов ассемблерного кода. Ну его нафиг! ![]() |
![]() |
Сообщ.
#1196
,
|
|
А нет волшебного ключика "сделай asm"? Как у Студии -FA, например. Мож он тогда только своё сгенерит, без всякой либовой обвязки
Добавлено Упс. В примерах кода прошмыгнуло чуток конфиденциальности. Подправил. |
Сообщ.
#1197
,
|
|
|
Цитата Qraizer @ А нет волшебного ключика "сделай asm"? Как у Студии -FA, например. Мож он тогда только своё сгенерит, без всякой либовой обвязки Увы, нету. Я изучил вопрос. Сам Дарт сперва компилячит в свое внутренне представление, а потом из него в код целевой платформы. Есть отдельный ключ - он компилячит в объектный файл, но там сигнатура ELF, да и размер тоже сравнимый с exe. Максимум, что я могу сделать - представить кусок кода на js, но это всё совсем не то. ![]() ![]() var A = { printString(string) { if (typeof dartPrint == "function") { dartPrint(string); return; } if (typeof console == "object" && typeof console.log != "undefined") { console.log(string); return; } if (typeof print == "function") { print(string); return; } throw "Unable to print message: " + String(string); }, _Universe_addRules(universe, rules) { return A._Utils_objectAssign(universe.tR, rules); }, _Universe_addErasedTypes(universe, types) { return A._Utils_objectAssign(universe.eT, types); }, _Utils_objectAssign(o, other) { var i, key, keys = Object.keys(other), $length = keys.length; for (i = 0; i < $length; ++i) { key = keys[i]; o[key] = other[key]; } }, main() { A.printString("42, hello"); } }; |
Сообщ.
#1198
,
|
|
|
Цитата Majestio @ Есть отдельный ключ - он компилячит в объектный файл, но там сигнатура ELF, да и размер тоже сравнимый с exe Скорми ELF в objdump |
Сообщ.
#1199
,
|
|
|
Цитата macomics @ Скорми ELF в objdump Файлы прикрепил. Прикреплённый файл ![]() Прикреплённый файл ![]() |
![]() |
Сообщ.
#1200
,
|
|
Та фик там что найдёшь. Я даже myfunc не нашёл, а main аж две.
P.S. Кстати, за либы. От так тож можно, ибо структурное связывание языковое, а не либовое: ![]() ![]() struct { int i1; int i2; int i3; } TranslateSysAddrToCS(unsigned SystemAddr); |