Кресты / Говнокод #18981 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
unsigned strlen(const char *str)
{
	const char *ptr;
	for (ptr = str; *ptr; ++ptr);
	return ptr - str;
}

char *strcpy(char *dst, const char *src)
{
	while((*dst++ = *src++) != 0);
	return dst;
}
namespace std
{
	class string
	{
	public:
		string(const char *str = 0) : size(str ? strlen(str) : 0)
		{
			this->str = new char[size + 1];
			if(str) strcpy(this->str, str);
			else this->str[0]=0;
		}
		string(const string &str) : size(str.size)
		{
			this->str = new char[size +1];
			strcpy(this->str, str.str);
		}
		~string()
		{
			delete[] str;
		}
		const char* c_str() const
		{
			return str;
		}
	private:
		char *str;
		unsigned size;
	};

	class Cout
	{
	public:
		Cout &operator<< (const char *str)
		{
			unsigned len = strlen(str);
			asm volatile (
			"movl $0x04, %%eax\n" 
			"movl $0x01, %%ebx\n"
			"int $0x80\n"
			:
			: "c"(str), "d"(len));
			return *this;
		}
		Cout &operator<< (const string &str)
		{
			operator<< (str.c_str());
			return *this;
		}
	} cout;
}

int main()
{
	std::string str = "Hello World!";
	std::cout << str << "\n";
	return 0;
}

Ещё 1 хелловорлд для линуха x86 на С++

Запостил: Koncord Koncord, (Updated )

Комментарии (52) RSS

  • Читер! new/delete надо было тоже делать через сисколлы.
    Ответить
  • Автор -- Бог переносимого кода.
    А не люблю AT&Tшный синтаксис
    Ответить
      • irony во все поля.
        Но всё же "Царь переносимого кода" звучало бы посильнее. С учётом местной специфики
        Ответить
      • Ошибаешься, на x86-64 тоже заведётся, в ядре оставлена совместимость.
        Ответить
        • Т.е. int 80h проверяет, какая битность у сегмента, который его позвал?
          Ответить
          • int 80h - это устаревший способ вызова функций ядра в x86-64. В x86-64 это можно сделать без прерываний, с помощью команды syscall, что на порядок быстрее и экономнее, но не совместимо с x86.
            Ответить
            • Ну вот мне что интересно - если на время забыть про sysenter/syscall, то int 80h, вроде как, работает и там и там. А коды сисколлов, емнип, разные (ну и аргументы само собой 64-битные у x86_64 и в других регистрах). Значит ядро отличает, когда запрос приходит из compatibility, а когда из long? Или я гоню?
              Ответить
              • Да, гоню. Нихера оно не отличает. int 80h всегда дёргает 32-битные сисколлы. 64-битные можно позвать только через syscall.
                Ответить
  • мне показалось, или тут тупо "копипаст всего что не скрыто дефайнами"?
    Ответить
    • Например? Если хочешь, могу полностью убрать stdlibc, но будет много ассемблера, а не только 1 вставка.
      Ответить
        • Ну апи в либе, а либу ему как раз таки хочется отпилить.

          На самом деле, в винде точно так же. Все эти kernel32.dll и.т.п. просто более высокоуровневые обёрточки над сисколлами, которые можно дёргать через int/sysenter/syscall.
          Ответить
          • Апи в дллке, в сишке кажется есть средства подключения к функциям дллок.
            Ответить
            • Апи чего? В ядро передать управление можно только прерыванием, sysenter'ом, syscall'ом и call gate'ом (но я не видел, чтобы оси call gate юзали). Всё остальное, что есть в dll'ках/so'шках - такие же бесправные юзермодные функции, как и у твоей проги. Никакой магии в них нет, ты всегда можешь написать их сам.

              А ОП как раз таки захотел написать прогу, которая не будет юзать все эти сахарные so'шки, а будет общаться только с ядром операционки.
              Ответить
              • Я думал, он не хочет подключать stdlibc. Мне так показалось, потому что он сам так написал.
                Отсутствие одного заголовка не мешает самому подключиться к нужным сошкам.
                Ответить
                • А в линухе всё основное api как раз в libc. Все эти read'ы, exit'ы это тонюсенькие обёртки над ядерными вызовами.

                  > одного заголовка
                  Ну и саму либу он тоже не линкует к проге.
                  Ответить
        • Ну, кстати, ещё вариант есть. Найти linux-gate.so в памяти, и позвать у него функцию, делающую сисколл одним из вышеперечисленных методов. Хотя... она тоже под асм заточена.
          Ответить
          • Я боюсь гэцэцэшных подставляемых символов. Мне они кажутся неинтуитивными.
            Ответить
            • Да там ёбаный пиздец. Куча мусора типа двойных процентов и долларов. Да ещё и всё вверх ногами. Неприятный ассемблер, если честно.

              Но интеграция того стоит - гцц старается, чтобы значения в нужных регистрах вовремя оказались и т.п. И в дизасме вставка не выглядит инородным телом, как в той же вижуалке.
              Ответить
              • Я не понимаю, для чего там макросы, заменяющиеся на регистры (типа "a" вместо ax/eax/rax). Это было бы объяснимо, если бы оно обеспечивало кроссплатформенность. Но ведь в любом случае при переносе на другую платформу придётся полностью переписывать все ассемблерные инструкции. Разве что иногда удастся сэкономить на замене eax→rax при портировании с x86 на x86_64.
                Ответить
                • Хер знает. Этот AT&T синтаксис вообще с какой архитектуры притащили? Может быть там все регистры однобуквенные были, как на тех же 8080.

                  Кстати, там же не только конкретные регистры можно писать, но и полезные штуки типа "любой регистр", "память", "память или регистр" и т.п.
                  Ответить
                  • не путайте Inline assambler с GCC AS это 2 разные вещи с одинаковым синтаксисом и GCC позволяет интел синтаксис
                    http://pastebin.com/CZGq2pLw
                    Парсер BBCode лох
                    "игнорировать \n" читай как "игнорировать \0"
                    Ответить
                • Видимо для того, чтобы не париться с разрядностью. Буква превращается в нужный регистр автоматически в зависимости от типа переменной, которую туда записывают.
                  Ответить
        • Это Си! И даже не попытка запилить stdlibc
          PS. Точка входа в Linux не main, а _start.
          Ответить
          • Ну _start по дефолту, а так - хоть чё можно задать. В общем-то в самом ELF она безымянная.

            Но я же написал, почему там main... ideone команду компилятора не даёт поправить.
            Ответить

Добавить комментарий

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8