LINUX.ORG.RU

AT&T asm: segmentation fault ?


0

0

Это попытка скопировать один участок памяти в другой.
Приводит почему-то к сегфолту :(

----------------------------------------------

static unsigned char *__dst;
static unsigned char *__src;
static int  __size;

inline void Class::cpy(unsigned char *buf)
{
    __dst = (unsigned char *)data;
    __src = buf;
    __size = m_dim1 * m_dim2; // 

__asm__ (
                        "ldsw __src, %si        \n\t"
                        "lesw __dst, %di        \n\t"
                        "movl __size, %ecx       \n\t"
                        "cld \n\t"
                        "rep movsd \n\t"
                    );
}
---------------------------------------------

Что не правильно ?
Спасибо.
anonymous

Ответ на: комментарий от kosmonavt

Здесь еще нюанс может быть. this может через EAX передаваться.

Совет: оттранслируй исходник в *.s и посмотри что к чему.

kosmonavt
()

Зачем 16-битный код?

"ldsw __src, %si        \n\t"
"lesw __dst, %di        \n\t"

kosmonavt
()

сорри, сейчас открылись ещё кое-какие вещи.

Если вместо этого кода вставить memcpy(data, buf, size) - всё работает правильно. Очевидно, асмовский код работает неверно (но работает!) и в итоге память data остаётся неинициализированной. При попытке её использования и получается сегфолт.

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

вот исходник, подредактированный
-----------------------------------

unsigned char *__dst;
unsigned char *__src;
int  __size;


void SQ_Pixmap::fillPixmap(unsigned char *buf)
{
    struct timeb tm;
    ftime(&tm);

    printf("s CONSTRUCTING QPIXMAP __MEMCPY__ START %u:%d\n", tm.time, tm.millitm);

//    memcpy(data, buf, m_width * m_height * 4);

    __dst = (unsigned char *)data;
    __src = buf;
    __size = m_width * m_height;// * 4;

__asm__ __volatile__(
                        "movl __src, %esi         \n\t"
                        "movl __dst, %edi        \n\t"
                        "movl __size, %ecx       \n\t"
                        "cld                             \n\t"
                        "rep movsd                  \n\t"

                    );

    ftime(&tm);
    printf("s CONSTRUCTING QPIXMAP __MEMCPY__ END   %u:%d\n", tm.time, tm.millitm);
}

вот .s
-------

.LCFI52:
        call    ftime
        addl    $16, %esp
        subl    $4, %esp
        movl    -20(%ebp), %eax
        andl    $65535, %eax
        pushl   %eax
        pushl   -24(%ebp)
        pushl   $.LC2
        call    printf
        addl    $16, %esp
        movl    8(%ebp), %eax
        movl    16(%eax), %eax
        movl    %eax, __dst
        movl    12(%ebp), %eax
        movl    %eax, __src
        movl    8(%ebp), %eax
        movl    8(%ebp), %edx
        movl    20(%eax), %eax
        imull   24(%edx), %eax
        movl    %eax, __size
#APP
        ldsl __src, %esi
        lesl __dst, %edi
        movl __size, %ecx
        cld
        rep movsd

#NO_APP
        subl    $12, %esp
        leal    -24(%ebp), %eax
        pushl   %eax
        call    ftime
        addl    $16, %esp
        subl    $4, %esp
        movl    -20(%ebp), %eax
        andl    $65535, %eax
        pushl   %eax
        pushl   -24(%ebp)
        pushl   $.LC3
        call    printf
        addl    $16, %esp
        leave
        ret

anonymous
()

Сейчас сюда придет очередной гномик - стороник:

1. оптимизирующих компиляторов, 2. идеологически правильных решений, 3. кроссплатформенных решений 4. етц...

И начнет рассказывать вам о том, как вредно писать код на асме, особенно для тех операций которые уже реализованны в стандартной библиотеке.

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

>anonymous (*) (07.04.2005 3:36:41)

PS. В это время надо спать или кое с кем развлекаться. Береги здоровье. Ну а asm на свежую голову.

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

Ну и пусть себе идет. Хреновый тот проргаммер, который в уме свой код дизасемблировать не может ( я имею в виде программистов на С или С++ ). Видать anonymous молодой - так пусть тренеруется. Я на 1-м курсе на зачет код на asm'е писал и затем ручками в native переводил.

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

PS. А то появились всякие там Нео и при виде натива в обморок падают.

"Мужчины заплакали и упали в обморок." - 1000 и одна ночь. :-)

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

Вот еще кое-что: либо ты мне не всю функцию показал, либо тут что-то не так.
Видишь код:

.LCFI52:
        call    ftime
        addl    $16, %esp


Здесь должен быть код для формирования фрейма стека функции.

Что-то вроде:

pushl %ebp
movl  %esp,%ebp
subl  ...,%esp


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

Смотри что получилось при трансляции
-------------------------------------------------
это *.cpp:
        "movl __src, %esi         \n\t"
        "movl __dst, %edi        \n\t"
        "movl __size, %ecx       \n\t"

а это *.s:
        ldsl __src, %esi
        lesl __dst, %edi
        movl __size, %ecx
-------------------------------------------------
ldsl и lesl - работают с сегментными регистрами. Вот здесь как раз и баг. Вообще фигня какая-то получилась.

У тебя какая версия gсс ? У меня в данный момент 3.2.2
Еще проверю дома на ASP10 и Слаке 10.1

Вот этот код у меня работает на ура:
----------------------------------------------------
#include <stdio.h>
#include <string.h>

char data[12];

unsigned char *__src, *__dst;
unsigned __size;

void cpy1(unsigned char* buf)
{
  __dst = (unsigned char*)data;
  __src = buf;
  __size = (strlen((char*)__src)+3)/4;
  __asm__ __volatile__ (
      "movl  __dst,  %edi\n\t"
      "movl  __src,  %esi\n\t"
      "movl  __size, %ecx\n\t"
      "cld\n\t"
      "rep   movsd"
  );
}

void cpy2(unsigned char* buf)
{
  __dst = (unsigned char*)data;
  __src = buf;
  __size = (strlen((char*)__src)+3)/4;
  __asm__ __volatile__ (
      "movl  __dst,  %%edi\n\t"
      "movl  __src,  %%esi\n\t"
      "movl  __size, %%ecx\n\t"
      "cld\n\t"
      "rep   movsd"::
  );
}

void cpy3(unsigned char* buf)
{
  __dst = (unsigned char*)data;
  __src = buf;
  __size = (strlen((char*)__src)+3)/4;
  __asm__ __volatile__ (
      "movl  %0, %%edi\n\t"
      "movl  %1, %%esi\n\t"
      "movl  %2, %%ecx\n\t"
      "cld\n\t"
      "rep   movsd"::"m"(__dst),"m"(__src),"m"(__size)
  );
}

void cpy4(void* __dst,const void* __src,unsigned __size)
{
  __asm__ __volatile__ (
      "movl  %0, %%edi\n\t"
      "movl  %1, %%esi\n\t"
      "movl  %2, %%ecx\n\t"
      "cld\n\t"
      "rep   movsd\n\t"::"m"(__dst),"m"(__src),"m"(__size)


  );
}

int main()
{
  char* s = "Hello world";

  cpy1((unsigned char*)s);
  puts(data);

  cpy2((unsigned char*)s);
  puts(data);

  cpy3((unsigned char*)s);
  puts(data);

  cpy4(data,s,(strlen(s)+3)/4);
  puts(data);

  return 0;
}

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

Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/specs
Configured with: ../configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++,ada,f77,objc,java,pascal --host=i586-mandrake-linux-gnu --with-system-zlib
Thread model: posix
gcc version 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk)


Ладно, всё равно спасибо за помощь. Я пытался просто сделать что-то быстрее, чем memcpy. Взял из DOOM3 SDK mmx-овый memcpy, кооторый копирует данные, выравненные на границу 64-х байт - написал отдельную программу, результат не впечатлил - прирост +10-15%. Не густо.

Ещё раз спасибо :)

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