Архитектурно-зависимые значения переменных (на C)

Модератор: Модераторы разделов

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

Всем привет!

Какой по вашему мнению самый интеллигентный способ инициализации переменных, значения которых зависят от архитектуры процессора?
Например, что-нибудь простенькое: есть char-переменная, надо на i686 туда положить "eax", на на x86_64 "rax" соответственно.
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

sciko
Сообщения: 1744
Статус: Ъ-участник
ОС: Debian/Ubuntu/etc

Re: Архитектурно-зависимые значения переменных

Сообщение sciko »

А вы ничего не путаете? Как бы "eax" и "rax" -- это ассемблер, а не C.
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

sciko писал(а):
30.01.2013 14:15
А вы ничего не путаете? Как бы "eax" и "rax" -- это ассемблер, а не C.

Хорошо, вот такой пример:

int a;
if (arch == i686) a = 1;
else a = 2;
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

Аватара пользователя
Женя Подсыпальников
Сообщения: 482

Re: Архитектурно-зависимые значения переменных

Сообщение Женя Подсыпальников »

Можа и не самый, но способ :)

Код: Выделить всё

void test() {
  char* pCh("default");
#ifdef _X86_
  pCh = "eax";
#endif
#ifdef _X64_
  pCh = "rax";
#endif
 //..
}


Я, правда, Си не очень, если что - вот это, но только о 32 и 64 битах ответ, не об архитектуре :)

Код: Выделить всё

#define size64 8
void test() {
  char* pCh("x86");
  if (size64 == sizeof(pCh)) {
    pCh = "x64";
  }
  //..
}
Пойдём на рыбалку !
Спасибо сказали:

sciko
Сообщения: 1744
Статус: Ъ-участник
ОС: Debian/Ubuntu/etc

Re: Архитектурно-зависимые значения переменных

Сообщение sciko »

И что он должен демонстрировать? Напоминаю: основная фишка C в том, что его можно скомпилировать, не задумываясь об особенностях реализации той или иной архитектуры. Ему вообще всё равно на какую архитектуру его собирают. Это проблемы компилятора и ОС.
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

Женя Подсыпальников

Ок, размер указателя это интересно :)

Код: Выделить всё

void arch() {
        char* pCh;
        if (sizeof(pCh) == 8) printf("x86_64\n");
        if (sizeof(pCh) == 4) printf("i686\n");
}


На этих двух платформах это должно сработать, но как только программа будет запущена, например, на ARM, который тоже 32 бит, мы получим конфликт с i686.
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

Аватара пользователя
Женя Подсыпальников
Сообщения: 482

Re: Архитектурно-зависимые значения переменных

Сообщение Женя Подсыпальников »

Дак а препроцессор на Си бывает чи не ? :)

Код: Выделить всё

// Arch.h
// Switch here before rebuild:
#define _ARM_
//#define _X86_
//#define _X64_

Код: Выделить всё

// test.c

#include "Arch.h"

void test() {
#if defined(_X86_)
  printf(..);
#elif defined(_X64_)
  printf(..);
#elif defined (_ARM_)
  printf(..);
#else
  printf(..);
#endif
}
Пойдём на рыбалку !
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

sciko писал(а):
30.01.2013 14:37
И что он должен демонстрировать? Напоминаю: основная фишка C в том, что его можно скомпилировать, не задумываясь об особенностях реализации той или иной архитектуры. Ему вообще всё равно на какую архитектуру его собирают. Это проблемы компилятора и ОС.

Да, я тоже сомневаюсь в правильности своего подхода, и прекрасно понимаю о чем Вы хотите сказать.

Но вот, к примеру, я делаю запрос через ptrace::

Код: Выделить всё

while (WIFSTOPPED(wait_status)) {
icounter++;
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.rip, 0); // <=== вот тут

printf("icounter = %u. RIP = 0x%08x. instr = 0x%08x\n",
icounter, regs.rip, instr);
}


Задача в том, чтобы корректно на 64 читать RIP, а на 32 - EIP из user_regs_struct, и наоборот. Поигрался с этим значением на разных машинах: приходится на 32 писать eip, а на 64 rip.....
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

Женя Подсыпальников писал(а):
30.01.2013 15:11
Дак а препроцессор на Си бывает чи не ? :)

Код: Выделить всё

// Arch.h
// Switch here before rebuild:
#define _ARM_
//#define _X86_
//#define _X64_


Switch here before rebuild точно не пойдет :) Вопрос-то был как это сделать интеллигентней ;)
Я тогда лучше вытащу архитектуру через uname()

Код: Выделить всё

#include <sys/utsname.h>
...
struct utsname info;
uname(&info);
printf("arch: %s\n, info.machine);


Но этот вариант мне тоже не нравится. Гонять режим процессора туда-сюда просто чтобы узнать архитектуру ИМХО не есть тру.
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

sciko
Сообщения: 1744
Статус: Ъ-участник
ОС: Debian/Ubuntu/etc

Re: Архитектурно-зависимые значения переменных

Сообщение sciko »

Так можно ж в Makefile объявить переменную соответствующую архитектуре и соответственно проверять её значение при компиляции.
Спасибо сказали:

Аватара пользователя
Stauffenberg
Сообщения: 2023
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: Архитектурно-зависимые значения переменных

Сообщение Stauffenberg »

sciko писал(а):
30.01.2013 16:07
Так можно ж в Makefile объявить переменную соответствующую архитектуре и соответственно проверять её значение при компиляции.

Как вариант кстати, да. Но хотелось бы найти решение именно через реализацию в коде.
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:

Аватара пользователя
Женя Подсыпальников
Сообщения: 482

Re: Архитектурно-зависимые значения переменных

Сообщение Женя Подсыпальников »

// Вопрос-то был как это сделать интеллигентней wink.gif

Нельзя забывать,
что машинный код ARM не стартанёт на MIPS или х86 машинах,
даже если Си компилятор что-то и разрешит попроверять в коде... :)
Пойдём на рыбалку !
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Архитектурно-зависимые значения переменных

Сообщение NickLion »

Вообще тут советуют:
It is better in the long run to check specifically for features you need, using a tool such as autoconf.


Если сильно хочется, то вот такой код работает:

Код: Выделить всё

#include <stdio.h>

int main()
{
#ifdef __x86_64__
    const char* c = "x86_64";
#endif
#ifdef __i686__
    const char* c = "i686";
#endif
    printf("%s\n", c);
    return 0;
}
Спасибо сказали: