LINUX.ORG.RU

Для HelloWorld Assembler лучший язык

 


0

2

http://www.opennet.ru/opennews/art.shtml?num=51992

Вот видео: https://2ton.com.au/videos/tvs_part1/tvs_part1.mp4

Кстати, заметил что даже для hello world он плохо тестил, не добавил флаги оптимизации:

https://imgur.com/a/zKaqZxG

Вот сравните: https://gcc.godbolt.org/z/DZQn4q

https://gcc.godbolt.org/z/fKpEkv

★★★★★

Последнее исправление: fsb4000 (всего исправлений: 2)

Хотел было опубликовать суждения о нынешнем «стиле разработки», но стал - «Зачем? Что изменится?».

Кратко скажу так - «Ныне не оптимальные алгоритмы не редки».

Владимир

anonymous
()

Для HelloWorld Assembler лучший язык

уровень раздела Development конца 2019

Virtuos86 ★★★★★
()

.

На счет оптимизации, gcc не умеет оптимизироваь по размеру -Os. Например, чтобы записать в регистр единицу (0x1), он тупо пишет константу вместо xor+inc. В общем случае оптимизация по размеру практически не нужна, так как практически мало пользы от него. Можно сказать, что размер -O2 больше в пределах погрешности измерений.

anonymous
()
Ответ на: . от anonymous

man gcc

-Os Optimize for size. -Os enables all -O2 optimizations except those that often increase code size:

-falign-functions -falign-jumps -falign-labels -falign-loops -fprefetch-loop-arrays -freorder-blocks-algorithm=stc

It also enables -finline-functions, causes the compiler to tune for code size rather than execution speed, and performs further optimizations designed to reduce code size.

Os ≈ O2

anonymous
()

Кстати, а gcc до сих пор в бинарник запихивает всё подряд?

$ cat > test.c
#include <stdio.h>
int main()
{
  printf("ok\n");
}
$ gcc -O3 -static test.c
$ ls -l
$ strip a.out
$ wc -c a.out
682696 a.out

Я не верю, что реализация prihtf 680KB занимает. Как сделать нормальный размер?

monk ★★★★★
()

Мне больше нравится подсчет суммы натурального ряда от 1 до 100.

Результат 5050 обязан знать любой программист /особенно это касается растовцев и гопников/.

Владимир

anonymous
()
Ответ на: комментарий от monk

Я не верю, что реализация prihtf 680KB занимает. Как сделать нормальный размер?

Там не из-за gcc, а из-за glibc, если использовать другую библиотеку то будет меньше.

На Windows, этот printf занимает около 1 мегабайта если использовать static версию MS libc и 80 килобайт если использовать libc вот этого компилятора: http://ladsoft.tripod.com/orange_c_compiler.html

Start-Process -PassThru hello.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
       192 ConEmuC.exe                                        C:\tools\cmdermini\vendor\conemu-maximus5\ConEmu\ConEmuC.exe
      2000 ntdll.dll                                          C:\WINDOWS\SYSTEM32\ntdll.dll
       356 wow64.dll                                          C:\WINDOWS\System32\wow64.dll
       524 wow64win.dll                                       C:\WINDOWS\System32\wow64win.dll
        40 wow64cpu.dll                                       C:\WINDOWS\System32\wow64cpu.dll

(Get-Item '.\hello.exe').length
81920

.\hello.exe
ok

Так что если ты хочешь уменьшить размер статического бинарника на Linux, то нужно прикрутить musl-libc или какой-нибудь diet libc или ещё какую-нибудь libc вместо glibc.

fsb4000 ★★★★★
() автор топика
Ответ на: комментарий от monk

Потому, что функции вызывают другие функции и понеслось. Поэтому и сделали musl, у которого все функции по максимуму независимые.

RazrFalcon ★★★★★
()
Ответ на: комментарий от monk

Скорее всего и на asm «Привет модераторам» с использованием glibc будет весить 1MB /скорее всего это не bug, а фича/.
Это - молодежно и современно.

Владимир

anonymous
()
Ответ на: комментарий от RazrFalcon

Потому, что функции вызывают другие функции и понеслось.

ОК. Заменил исходник на

#include <unistd.h>
int main()
{
  write(1,"ok\n", 3);
}

Исходник функции write:

ssize_t
__libc_write (int fd, const void *buf, size_t nbytes)
{
  return SYSCALL_CANCEL (write, fd, buf, nbytes);
}

Объём бинарника всё равно 680KB.

monk ★★★★★
()
Ответ на: комментарий от monk

У меня из Linux только armbian есть, так что размер немного не сойдётся с твоим, и я попробовал собрать твой пример там:

cat main.c
#include <stdio.h>
int main()
{
  printf("ok\n");
}

gcc -O3 -static main.c -o glibc

musl-gcc -O3 -static main.c -o musl

ldd musl 
	не является динамическим исполняемым файлом

ldd glibc
	не является динамическим исполняемым файлом

ll
итого 588
-rwxr-xr-x 1 fsb4000 fsb4000 571120 дек  8 13:41 glibc
-rw-r--r-- 1 fsb4000 fsb4000     52 дек  8 13:41 main.c
-rwxr-xr-x 1 fsb4000 fsb4000  20504 дек  8 13:41 musl

Чтобы появился musl-gcc в Debian нужно установить: https://packages.debian.org/unstable/musl-tools

fsb4000 ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

Про musl я в курсе. Но для него либо всё пересобирать, либо дистрибутив менять.

Просто странно, что компилятор до сих пор не умеет выкидывать недосягаемый код.

monk ★★★★★
()
Ответ на: комментарий от monk
#include <unistd.h>

#define HELLO "Hello world!\n"

void _start (void) {
  write(1, HELLO, sizeof(HELLO));
  _exit(0);
}
$ gcc -Os -static -o minimal minimal.c -nostartfiles -s -Wl,-nN
$ wc -c minimal
1488 minimal
$ ./minimal
Hello world!
anonymous
()
Ответ на: комментарий от monk

выкидывать недосягаемый код

А код точно недосягаем? Я тут краем глаза глянул, __libc_start_main вызывает много чего, кроме самого __main. Например, __libc_check_standard_fds. Которая вызывает __libc_fcntl. Которая вызывает __libc_enable_asynccancel. Которая вызывает _nl_current_LC_TYPE. Которая …

gremlin_the_red ★★★★★
()
Ответ на: комментарий от anonymous

есть ещё гугловские сборки под Linux полноценного Tcl размером 817.95KB и Tcl/Tk размером порядка 1.45MB
https://code.google.com/archive/p/tclkit/downloads

не «Hello World!», почти Lisp, со смешными размерами реализации )
реализацию можно в дистрибутив с исходниками закидывать,
или исходники можно в .kit паковать, а можно и в исполняемый файл

anonymous
()
Ответ на: комментарий от gremlin_the_red

__libc_start_main вызывает много чего, кроме самого __main. Например, …

полмегабайта мусора просто для запуска программы! Я теперь начинаю понимать парней с suckless.org

monk ★★★★★
()

Вброшу. 2 сискола на си.

$ cat syscall.c 
#include <unistd.h>
#include <sys/syscall.h>

#define HELLO "Hello world!\n"

void _start() {
    syscall(SYS_write, 1, HELLO, sizeof(HELLO));
    syscall(SYS_exit, 0);
}
$ gcc -Os -static -o syscall syscall.c -nostartfiles -s -Wl,-n
$ strip -R '*' -R '!.text' -R '!.rodata' syscall
$ wc -c syscall
640 syscall
$ strace -c ./syscall
Hello world!
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         1           write
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                     2           total
anonymous
()
Ответ на: комментарий от monk

Я не верю, что реализация prihtf 680KB занимает. Как сделать нормальный размер?

После -O3 там никакого printf() не остаётся.

EXL ★★★★★
()

ассемблер

опубликовал видео

А мсье знает толк.

hobbit ★★★★★
()
Ответ на: комментарий от anonymous

640 syscall

Что-то всё равно много. 64 байта заголовок ELF, 98 байт код, 14 байт данные. А куда ещё 464 байта ушло?

monk ★★★★★
()
Ответ на: комментарий от monk
.data
msg:
  .ascii "Hello, world!\n"
  .set len, . - msg

.text

.globl _start
_start:
  # write
  mov  $1,   %rax
  mov  $1,   %rdi
  mov  $msg, %rsi
  mov  $len, %rdx
  syscall

  # exit
  mov  $60, %rax
  xor  %rdi, %rdi
  syscall
as --64 hello-syscall.s -o hello-syscall.o
ld -melf_x86_64 -s hello-syscall.o -o hello-syscall

https://github.com/BR903/ELFkickers/tree/master/sstrip

sstrip hello-syscall
wc -c hello-syscall
234 hello-syscall

А C-шный syscall получился

453 syscall

vodz ★★★★★
()
Ответ на: комментарий от monk

полмегабайта мусора

С чего мусора-то? Полезные функции. Можно, конечно, было навелосипедить отдельную минималистическую функцию, которая не зависела бы от других функций, но зачем? При динамической линковке никаких проблем нет же. А статическая линковка сосёт.

парней с suckless.org

Этих укуренных идиотов, которых на пушечный выстрел нельзя подпускать к программированию?

gremlin_the_red ★★★★★
()

Тест как минимум не внушает доверия, он использует второй питон, а это уже о многом говорит. Не указаны ни версии интерпретаторов, не компиляторов

anonymous
()
Ответ на: комментарий от monk

А куда ещё 464 байта ушло?

На мусор, напиханный gcc и binutils/ld.

Я не ставил целью получить минимальный экзешник. Я показал, что на си легко можно получить заветные 2 сискола.

anonymous
()
Ответ на: комментарий от anonymous

+Help, tutorials and examples for the Red programming language: http://helpin.red/

В контексте ветки интересны больше не учебники, а измерения производительности в сравнении с C++.

monk ★★★★★
()

History of the Unix-speaking Peoples

anonymous
()
Ответ на: комментарий от monk

crtstartup.o и всякая хрень всё равно линкуются. Тебе нужен -nostdlib или что-то там ещё.

anonymous
()
Ответ на: комментарий от gremlin_the_red

При динамической линковке никаких проблем нет же. А статическая линковка сосёт.

Из-за вас, таких умников, я и наблюдаю образы докера в 2гига размером.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

Из-за вас, таких умников, я и наблюдаю образы докера в 2гига размером.

Так и сам докер появился, потому что такие умники поломали статическую линковку.

monk ★★★★★
()
Ответ на: комментарий от monk

Говорят асинк в вебе опасен, так как можно допустить утечку памяти когда клиенты реконнектятся. В ракете можно убивать континуейшены по таймауту? Вот например в расте с явным рантаймом для фьюч такое можно организовать.

q0tw4 ★★★★
()
Ответ на: комментарий от q0tw4

В ракете можно убивать континуейшены по таймауту?

Да. Там это по-умолчанию. Точнее не совсем таймаут, а make-threshold-LRU-manager – протухает быстрее, если осталось мало памяти.

А всё, что привязано к продолжениям/замыканиям, автоматически собирается сборщиком мусора.

monk ★★★★★
()
Ответ на: комментарий от monk

На счет сборщика мусора тут та же песня, что и с кешированием. Если кодер желает сохранить в памяти что-то, только он и может решить когда это может быть удалено (впрочем я как раз сейчас делаю систему в которой удаленные элементы могут быть перезаписаны при необходимости, но если они не были перезаписаны, то их повторное добавление воскрешает их из мусора). Для веба правильнее всего было бы не просто убивать продолжения когда кончилась память, а скидывать их при этом в базу данных. Вот интересно, в каком языке продолжения/фьючи/кактамононазывается, генерируемые системой (а то можно и руками их писать в любом ЯП) в принципе могут быть сериализованы? Обычно же это некие приватные для рантайма структуры, которые даже склонировать не возможно, не говоря уж о сериализации.

q0tw4 ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.