LINUX.ORG.RU

OpenGL + nasm -> вроде прорисовывается, но сразу падает


0

0

Ниже пример программы nasm + opengl. После компиляции падает. Вопрос - почему? Если запускать в gdb , затем команда run окошко и цветной треугольник прорисовывается, т.е. до какойто степени оно работает.


help me please


; ----------------------------------------------------------------------------
; triangle.asm
;
; A very simple *Windows* OpenGL application using the GLUT library.  It
; draws a nicely colored triangle in a top-level application window.  One
; interesting thing is that the Windows GL and GLUT functions do NOT use the
; C calling convention; instead they use the "stdcall" convention which is
; like C except that the callee pops the parameters.
; ----------------------------------------------------------------------------

        global  main
        extern  glClear
        extern  glBegin
        extern  glEnd
        extern  glColor3f
        extern  glVertex3f
        extern  glFlush
        extern  glutInit
        extern  glutInitDisplayMode
        extern  glutInitWindowPosition
        extern  glutInitWindowSize
        extern  glutCreateWindow
        extern  glutDisplayFunc
        extern  glutKeyboardFunc
        extern  glutPostRedisplay
        extern  glutReshapeFunc
        extern  glutMainLoop

        section .text
title:  db      'A Simple Triangle', 0
zero:   dd      0.0
one:    dd      1.0
half:   dd      0.5
neghalf:dd      -0.5

display:
        push    dword 16384
        call    glClear              ; glClear(GL_COLOR_BUFFER_BIT)
        push    dword 9
        call    glBegin              ; glBegin(GL_POLYGON)
        push    dword 0
        push    dword 0
        push    dword [one]
        call    glColor3f           ; glColor3f(1, 0, 0)
        push    dword 0
        push    dword [neghalf]
        push    dword [neghalf]
        call    glVertex3f          ; glVertex(-.5, -.5, 0)
        push    dword 0
        push    dword [one]
        push    dword 0
        call    glColor3f           ; glColor3f(0, 1, 0)
        push    dword 0
        push    dword [neghalf]
        push    dword [half]
        call    glVertex3f          ; glVertex(.5, -.5, 0)
        push    dword [one]
        push    dword 0
        push    dword 0
        call    glColor3f           ; glColor3f(0, 0, 1)
        push    dword 0
        push    dword [half]
        push    dword 0
        call    glVertex3f          ; glVertex(0, .5, 0)
        call    glEnd                ; glEnd()
        call    glFlush              ; glFlush()
        ret

keyboard:
	  pop    ebx;
	  pop    ebx;
	  pop    ebx;
	  call   glutPostRedisplay
	  ret
	  
reshape:
	  pop    ebx;
	  pop    ebx;
	  ret

main:
        push    dword [esp+8]           ; push argv
        lea     eax, [esp+8]            ; get addr of argc (offset changed :-)
        push    eax
        call    glutInit             ; glutInit(&argc, argv)
        push    dword 0
        call    glutInitDisplayMode
        push    dword 80
        push    dword 80
        call    glutInitWindowPosition
        push    dword 300
        push    dword 400
        call    glutInitWindowSize
        push    title
        call    glutCreateWindow
        push    display
        call    glutDisplayFunc
        call    glutMainLoop
        ret


 
anonymous

да-да, C для лохов. на нём программы медленнее, зато рабочие.

max_posedon
()

$@!#%*@!%#&^%&^@!#*!@#%$^!$^! !!!!!!!

Сэээр, куда Вы полезли с таким знанием ассемблера ?

Падает она на первом же вызове ret в функции display. Ибо:

"Очистка параметров на стеке в языке Cи возлагается на вызывающую функцию."

Соответственно после каждого call должен стоять :

add esp,(количество_параметров*выравнивание_аргументов_на_стеке)

Надеюсь, понятно, почему оно на ret крашится ?

Darkman ★★★
()

> OpenGL + nasm

сурово...

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

One interesting thing is that the Windows GL and GLUT functions do NOT use the C calling convention; instead they use the "stdcall" convention which is like C except that the callee pops the parameters.

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

> One interesting thing is that the Windows GL (...)

Windows. Not *nix. Если это собиралось под linux, то да, именно там оно и упадёт. Если писалось и собиралось под win32, то какого ..я этот вопрос делает на LORе?

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

>Очистка параметров на стеке в языке Cи

^W^W^Wв архитектуре x86. Ибо во всех нормальных (даже в x86_64) параметры давно передаются через регистры.

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

#ifndef GLAPI
# ifdef _WIN32
#  define GLAPI __stdcall
# else
#  define GLAPI
# endif
# define __DEFINED_GLAPI
#endif


Какая буква в этом слове вам непонятна, сэ-э-эр?

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

Это да, вы правы. Я смотрел на эти примеры под Win32 для nasm:

http://www.cs.lmu.edu/~ray/notes/nasmexamples/

всё нормально работало на Линухе, кроме opengl. Видимо со стеком и ret для Линуха я так понимаю придётся разбираться. Я правильно понимаю куда копать?

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

В какого рода документации обычно пишут такие тонкости? Если я правильно понял, многое зависит от ОС и аппаратиной архитектуры. Т.е. об этом должно быть написано в доке на конкретную ОС для конкретной аппаратной архитектуры? Как обычно называется подобный мануал?

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

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

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

вся проблема возникает в несовместимости между компиляторами, различными версиями одного компилятора или вообще ключами компиляции. потому обычно такие функции не экспортируются.

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

Да, там написано практически всё.

>...Как обычно называется подобный мануал?

ABI.

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

> ^W^W^Wв архитектуре x86. Ибо во всех нормальных (даже в x86_64) параметры давно передаются через регистры.

Ышшо одын. Зуб даёшь ?

#include <stdio.h>

int main ()
{
        printf ("Hello %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d!\n",1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8);
        return 0;
}

~/tmp> gcc -S t.c

.LC0:
        .string "Hello %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d!\n"
        .text
.globl main
        .type   main, @function
main:
.LFB2:
        pushq   %rbp
.LCFI0:
        movq    %rsp, %rbp
.LCFI1:
        subq    $112, %rsp
.LCFI2:
        movl    $8, 96(%rsp)
        movl    $7, 88(%rsp)
        movl    $6, 80(%rsp)
        movl    $5, 72(%rsp)
        movl    $4, 64(%rsp)
        movl    $3, 56(%rsp)
        movl    $2, 48(%rsp)
        movl    $1, 40(%rsp)
        movl    $0, 32(%rsp)
        movl    $9, 24(%rsp)
        movl    $8, 16(%rsp)
        movl    $7, 8(%rsp)
        movl    $6, (%rsp)
        movl    $5, %r9d
        movl    $4, %r8d
        movl    $3, %ecx
        movl    $2, %edx
        movl    $1, %esi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        leave
        ret

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

Оно дышит:

; ----------------------------------------------------------------------------
; triangle.asm
;
; A very simple *Windows* OpenGL application using the GLUT library.  It
; draws a nicely colored triangle in a top-level application window.  One
; interesting thing is that the Windows GL and GLUT functions do NOT use the
; C calling convention; instead they use the "stdcall" convention which is
; like C except that the callee pops the parameters.
; ----------------------------------------------------------------------------

        global  main
        extern  puts
        extern  glClear
        extern  glBegin
        extern  glEnd
        extern  glColor3f
        extern  glVertex3f
        extern  glFlush
        extern  glutInit
        extern  glutInitDisplayMode
        extern  glutInitWindowPosition
        extern  glutInitWindowSize
        extern  glutCreateWindow
        extern  glutDisplayFunc
        extern  glutKeyboardFunc
        extern  glutPostRedisplay
        extern  glutReshapeFunc
        extern  glutMainLoop

        section .text
title:  db      'A Simple Triangle', 0
message:  db    'glutKeyboardFunc - key pressed!', 0
zero:   dd      0.0
one:    dd      1.0
half:   dd      0.5
neghalf:dd      -0.5


display:
        push    dword 16384
        call    glClear              ; glClear(GL_COLOR_BUFFER_BIT)
	  add     esp,4 
        push    dword 9
        call    glBegin              ; glBegin(GL_POLYGON)
	  add     esp,4 
;	  pop	    eax
        push    dword 0
        push    dword 0
        push    dword [one]
        call    glColor3f           ; glColor3f(1, 0, 0)
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
	  add     esp,12 
        push    dword 0
        push    dword [neghalf]
        push    dword [neghalf]
        call    glVertex3f          ; glVertex(-.5, -.5, 0)
	  add     esp,12 
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
        push    dword 0
        push    dword [one]
        push    dword 0
        call    glColor3f           ; glColor3f(0, 1, 0)
	  add     esp,12 
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
        push    dword 0
        push    dword [neghalf]
        push    dword [half]
        call    glVertex3f          ; glVertex(.5, -.5, 0)
	  add     esp,12 
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
        push    dword [one]
        push    dword 0
        push    dword 0
        call    glColor3f           ; glColor3f(0, 0, 1)
	  add     esp,12 
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
        push    dword 0
        push    dword [half]
        push    dword 0
        call    glVertex3f          ; glVertex(0, .5, 0)
	  add     esp,12 
;	  pop	    eax
;	  pop	    eax
;	  pop	    eax
        call    glEnd                ; glEnd()
        call    glFlush              ; glFlush()
        ret

keyboard:
;	  pop    ebx;
;	  pop    ebx;
;	  pop    ebx;
	  push message
	  call puts
	  add esp,4
	  call   glutPostRedisplay
	  ret
	  
reshape:
;	  pop    ebx;
;	  pop    ebx;
	  ret

main:
        push    dword [esp+8]           ; push argv
        lea     eax, [esp+8]            ; get addr of argc (offset changed :-)
        push    eax
        call    glutInit             ; glutInit(&argc, argv)
        push    dword 0
        call    glutInitDisplayMode
        push    dword 80
        push    dword 80
        call    glutInitWindowPosition
        push    dword 300
        push    dword 400
        call    glutInitWindowSize
        push    title
        call    glutCreateWindow
        push    display
        call    glutDisplayFunc
	  push    reshape
	  call    glutReshapeFunc
	  push    keyboard
	  call    glutKeyboardFunc
        call    glutMainLoop
        ret



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

Что именно непонятно уважаемому сэру?

Вот эта часть что ли:

movl $5, %r9d
movl $4, %r8d
movl $3, %ecx
movl $2, %edx
movl $1, %esi
movl $.LC0, %edi
movl $0, %eax

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