flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2 |
Author |
|
Furs 27 Jun 2022, 13:20
btw if you want to search for something you should use find:
Code: find /usr/lib -name 'libSDL*' Can also restrict it a lot more, e.g. common one is -type f (so it only shows files). |
|||
![]() |
|
FlierMate1 27 Jun 2022, 14:42
Furs wrote: ... if you want to search for something you should use find: Yes, I think this is the proper way. There is similar command "locate" but need to install separately.
|
||||||||||
![]() |
|
revolution 27 Jun 2022, 14:46
If you only have SDL2 then the code won't work. It is not backward compatible.
Someone on SO might have a possible solution: https://stackoverflow.com/questions/28400401/sdl-setvideomode-identifier-not-found Last edited by revolution on 27 Jun 2022, 14:54; edited 1 time in total |
|||
![]() |
|
FlierMate1 27 Jun 2022, 14:47
Sorry for many large screenshots, Debian 11 is on VirtualBox, no copy-paste between host and guest, the fastest way is to capture screenshot.
|
|||
![]() |
|
FlierMate1 27 Jun 2022, 14:54
revolution wrote: If you only have SDL2 then the code won't work. It is not backward compatible. I am more interested if anyone can fix his minimal GUI example (Xlib 11) so that at least it can displays "Hello, world" text string. |
|||
![]() |
|
FlierMate1 27 Jun 2022, 15:19
Finally, I can see the demo screen!! On 64-bit Linux.
|
||||||||||||||||||||||||||||
![]() |
|
revolution 25 Jan 2023, 07:16
revolution wrote: It is possible to make a 64-bit version also that is under 1K. Using the standard fasm elf formatter without any special tricks the interpreter header can be eliminated, leaving just two: the LOAD and DYNAMIC headers.
Code: check_errors = 0 ; set to 1 to compile with error checking x_res = 533 ; default start width y_res = 300 ; default start height buffer_size = 2000 ; make enough space to capture error text from the library ;Versions ;OpenGL GLSL ;2.0 1.10 <--- this code ;2.1 1.20 ;3.0 1.30 ;3.1 1.40 ;3.2 1.50 ;3.3 3.30 ;/usr/include/SDL/SDL.h ;/usr/include/SDL/SDL_video.h ;/usr/include/SDL/SDL_events.h SDL_INIT_VIDEO = 0x20 SDL_OPENGL = 0x00000002 SDL_RESIZABLE = 0x00000010 SDL_FULLSCREEN = 0x80000000 SDL_FULLSCREEN_BIT = 31 SDL_KEYDOWN = 2 SDL_QUIT = 12 SDL_VIDEORESIZE = 16 ;/usr/include/GL/gl.h ;/usr/include/SDL/SDL_opengl.h GL_LINE_LOOP = 0x0002 GL_TRIANGLES = 0x0004 GL_TRIANGLE_STRIP = 0x0005 GL_TRIANGLE_FAN = 0x0006 GL_POLYGON = 0x0009 GL_FRONT = 0x0404 GL_BACK = 0x0405 GL_FRONT_AND_BACK = 0x0408 GL_CW = 0x0900 GL_CCW = 0x0901 GL_CULL_FACE = 0x0b44 GL_DEPTH_TEST = 0x0b71 GL_VIEWPORT = 0x0ba2 GL_MODELVIEW = 0x1700 GL_PROJECTION = 0x1701 GL_POINT = 0x1b00 GL_LINE = 0x1b01 GL_FILL = 0x1b02 GL_FRAGMENT_SHADER = 0x8b30 GL_VERTEX_SHADER = 0x8b31 GL_COMPILE_STATUS = 0x8b81 GL_VALIDATE_STATUS = 0x8b83 GL_DEPTH_BUFFER_BIT = 0x00000100 GL_COLOR_BUFFER_BIT = 0x00004000 GL_NO_ERROR = 0 GL_FALSE = 0 SYS_WRITE = 1 SYS_EXECVE = 59 SYS_EXIT = 60 STD_OUTPUT = 1 DT_NULL = 0 DT_NEEDED = 1 DT_STRTAB = 5 DT_SYMTAB = 6 DT_DEBUG = 21 DT_GNU_HASH = 0x6ffffef5 macro encode text, length { bits = 0 accum = 0 offset = 0 while offset < length load c byte from text+offset if c = char_escape | c >= 0x7f display c shr 6 + '0', c shr 3 and 7 + '0', c and 7 + '0', 10 err ; bad character end if if (c >= 0x40 & c <= 0x5e) | c <= 0x1f store byte c + 0x20 at text+offset offset = offset - 1 c = char_escape end if if c >= 0x5f c = c - 0x3f else c = c - 0x20 end if accum = accum + c shl bits bits = bits + 6 if bits > 18 dw accum and 0xffff db accum shr 16 bits = 0 accum = 0 end if offset = offset + 1 end while if bits > 12 dw accum and 0xffff db accum shr 16 else if bits > 6 dw accum else if bits > 0 db accum end if } char_escape = '`' ; for uppercase and control characters functions equ macro invoke proc, [arg] { common regr equ rdi, rsi, rdx, rcx, r8, r9, -, - rege equ edi, esi, edx, ecx, r8d, r9d, -, - if ~ arg eq forward match rreg =, shiftr =| ereg =, shifte, regr | rege \{ regr equ shiftr rege equ shifte if arg eqtype 0 & 0 = arg xor ereg, ereg else if arg eqtype 0 & 0x80 > arg & -0x80 <= arg push arg pop rreg else if arg eqtype 0 & 1 shl 32 > arg & 0 <= arg mov ereg, arg else if ~ rreg eq arg if arg in <rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp> push arg pop rreg else mov rreg, arg end if end if \} common end if if check_errors local .proc_name, .skip_proc_name test spl,0xf lea rax,[.proc_name] jnz stack_alignment_fault jmp .skip_proc_name .proc_name: db .skip_proc_name - .proc_name - 1, `proc .skip_proc_name: end if call [rbp+proc-procs] found equ 0 match a =proc b,x functions y \{ found equ 1 \} match =0, found \{ functions equ functions, proc \} } ; invoke with error check macro einvoke proc, [arg] { common local .okay, .proc_name invoke proc,arg if check_errors invoke glGetError assert GL_NO_ERROR = 0 test rax,rax jz .okay push rax mov edx,.okay - .proc_name lea esi,[.proc_name] push STD_OUTPUT SYS_WRITE pop rax rdi syscall pop rax jmp error .proc_name: db `proc,10 .okay: end if } ; invoke with return value check macro rinvoke proc, [arg] { common local .okay, .proc_name invoke proc,arg if check_errors test rax,rax jnz .okay push rax mov edx,.okay - .proc_name lea esi,[.proc_name] push STD_OUTPUT SYS_WRITE pop rax rdi syscall pop rax jmp error .proc_name: db `proc,10 .okay: end if } virtual org 0 struc r_debug { .r_version rq 1 ; version number for this protocol .r_map rq 1 ; head of the chain of loaded objects .r_brk rq 1 ; breakpoint for debugger to monitor .so mapping changes .r_state rq 1 ; object mapping state .r_ldbase rq 1 ; base address the linker is loaded at }r_debug r_debug org 0 struc link_map { .l_addr rq 1 ; library load address .l_name rq 1 ; file name of library .l_ld rq 1 ; dynamic section of library .l_next rq 1 ; next in chain .l_prev rq 1 ; previous in chain }link_map link_map org 0 struc gnu_hash { .bucket_count rd 1 .sumbol_offset rd 1 .bloom_size rd 1 .bloom_shift rd 1 .bucket_list rb 0 }gnu_hash gnu_hash org 0 struc Elf64_Sym { .st_name rd 1 .st_info rb 1 .st_other rb 1 .st_shndx rw 1 .st_value rq 1 .st_size rq 1 }Elf64_Sym Elf64_Sym sizeof.Elf64_Sym = $ end virtual format ELF64 executable 3 at 0x10000 entry begin segment dynamic dq DT_NEEDED,GL - $$ dq DT_NEEDED,SDL - $$ dq DT_STRTAB,rva $$ dq DT_DEBUG dt_debug dq ? dq DT_SYMTAB;,0 ;dq DT_NULL,0 interpret: mov al,SYS_EXECVE assert procs = interpreter push rsp rbp pop rdi rsi rdx push rdi segment readable writeable executable lea rdx,[rsi+(rdx+2)*8] syscall if check_errors jmp kill end if begin: mov ebp,procs push proc_count-1 pop r13 push [dt_debug] .link_loop: pop rax test rax,rax jz interpret mov rdi,[rax+r_debug.r_map] push rax .library_loop: mov rsi,[rdi+link_map.l_name] cmp byte[rsi],0 jz .next_library mov rsi,[rdi+link_map.l_ld] ; rsi = dynamic section .find_tables_loop: lodsq cmp eax,DT_GNU_HASH cmovz rbx,[rsi] ; rbx = gnu hash table cmp eax,DT_SYMTAB cmovz r14,[rsi] ; r14 = symbol table test eax,eax lodsq jnz .find_tables_loop xchg edx,eax ; rdx = 0 mov eax,[rbp+r13*4-procs+hashes] mov ecx,[rbx+gnu_hash.bucket_count] ; rcx = bucket count mov esi,eax ; rsi = target hash div ecx ; rdx = target bucket mov eax,[rbx+gnu_hash.bloom_size] lea rax,[rbx+rax*8+gnu_hash.bucket_list] ; rax = bucket list lea rcx,[rax+rcx*4] ; rcx = hash chains mov edx,[rax+rdx*4] ; rdx = chain/symbol index sub edx,[rbx+gnu_hash.sumbol_offset] ; adjust symbol offset jb .next_library and esi,not 1 .find_symbol_loop: mov eax,[rcx+rdx*4] xor eax,esi shr eax,1 ; bit 0 = set, marks the end of the chain jz .found_symbol inc edx jnc .find_symbol_loop .next_library: mov rdi,[rdi+link_map.l_next] if check_errors test rdi,rdi jnz .library_loop jmp kill else jmp .library_loop end if .found_symbol: add edx,[rbx+gnu_hash.sumbol_offset] imul edx,edx,sizeof.Elf64_Sym mov rax,[r14+rdx+Elf64_Sym.st_value] add rax,[rdi+link_map.l_addr] mov [rbp+r13*8-procs+hashes],rax dec r13 jns .link_loop ; invoke SDL_Init,SDL_INIT_VIDEO if check_errors test rax,rax jnz error end if push SDL_OPENGL or SDL_RESIZABLE pop r13 call set_video rinvoke glCreateProgram xchg r15,rax ; r15 = program push rax ; stack align mov esi,shaders push shader_count pop rcx .next_shader: push rcx lea edi,[rbp-procs+shader_text] push rdi .next_quad: lodsd dec esi shl eax,8 mov cl,4 .next_byte: dec cl js .next_quad ror eax,6 shr al,2 add al,0x20 cmp al,0x3f jbe .byte_ready add al,0x5f-0x40 .byte_ready: xor al,ch ; apply escape mov ch,0x20 ; enable escape mode cmp al,char_escape jz .next_byte stosb mov ch,0 ; disable escape mode cmp al,0 jnz .next_byte sub ecx,1 sbb esi,ecx lodsw ; load shader type movzx edi,ax pop rax push rsi rax rinvoke glCreateShader,rdi xchg rbx,rax ; rbx = shader einvoke glShaderSource,rbx,1,rsp,0 einvoke glCompileShader,rbx if check_errors push rax ; stack align call shader_log push GL_FALSE invoke glGetShaderiv,rbx,GL_COMPILE_STATUS,rsp pop rax cmp rax,GL_FALSE pop rax ; stack align jz error end if einvoke glAttachShader,r15,rbx pop rax rsi rcx if check_errors dec cl jnz .next_shader else loop .next_shader end if pop rax ; stack align einvoke glLinkProgram,r15 if check_errors invoke glValidateProgram,r15 push rax ; stack align call program_log push GL_FALSE invoke glGetProgramiv,r15,GL_VALIDATE_STATUS,rsp pop rax cmp rax,GL_FALSE pop rax ; stack align jz error end if einvoke glUseProgram,r15 rdtsc xchg r15,rax ; r15 = time offset invoke glEnable,GL_DEPTH_TEST .animation_loop: einvoke glClear,GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT invoke SDL_GetTicks add rax,r15 and eax,shader_period push qword[rbp-procs+current_width] rax ; w = height, z = width, y = point, x = time mov bl,shader_faces .face_loop: invoke glBegin,GL_POLYGON mov bh,shader_sides .vertex_loop: invoke glVertex4iv,rsp inc dword[rsp+4] dec bh jnz .vertex_loop einvoke glEnd dec bl jnz .face_loop pop rax rax invoke SDL_GL_SwapBuffers .get_event: lea edi,[rbp-procs+SDL_Event] invoke SDL_PollEvent,rdi test eax,eax jz .animation_loop mov al,[rbp-procs+SDL_Event] cmp al,SDL_VIDEORESIZE jne .not_resized push qword[rbp-procs+SDL_width] pop qword[rbp-procs+framed_width] .set_frame: call set_video mov edx,[rbp-procs+current_width] mov ecx,[rbp-procs+current_height] invoke glViewport,0,0,rdx,rcx jmp .get_event .not_resized: cmp al,SDL_QUIT je quit cmp al,SDL_KEYDOWN jne .get_event btc r13,SDL_FULLSCREEN_BIT cmp [rbp-procs+SDL_key],'f' je .set_frame quit: invoke SDL_Quit xor edi,edi kill: push SYS_EXIT pop rax syscall set_video: push rax ; stack align mov edi,[rbp-procs+framed_width] mov esi,[rbp-procs+framed_height] assert SDL_FULLSCREEN_BIT = 31 test r13d,r13d setns bl jns .set invoke SDL_ListModes,0,r13 if check_errors cmp rax,0 jle error end if mov rax,[rax] movzx edi,word[rax+4] movzx esi,word[rax+6] .set: mov [rbp-procs+current_width],edi mov [rbp-procs+current_height],esi rinvoke SDL_SetVideoMode,rdi,rsi,0,r13 movzx edi,bl invoke SDL_ShowCursor,rdi pop rax ; stack align ret if check_errors error: sub rsp,20 mov rsi,rsp push 15 pop rcx .next_nibble: mov edx,eax and edx,0xf mov dl,[hex_table+rdx] mov [rsi+rcx],dl shr rax,4 dec ecx jns .next_nibble mov byte[rsi+16],10 push STD_OUTPUT SYS_WRITE 17 pop rdx rax rdi syscall add rsp,20 jmp quit program_log: lea edx,[log_buffer] lea ecx,[rdx+8] push 0 pop qword[rdx] invoke glGetProgramInfoLog,r15,buffer_size,rdx,rcx jmp log shader_log: lea edx,[log_buffer] lea ecx,[rdx+8] push 0 pop qword[rdx] invoke glGetShaderInfoLog,rbx,buffer_size,rdx,rcx log: mov rdx,qword[log_buffer] test rdx,rdx jz .ret lea esi,[log_buffer+8] push STD_OUTPUT SYS_WRITE pop rax rdi syscall .ret: ret stack_alignment_fault.message: db ': Stack alignment error',10 stack_alignment_fault: movzx edx,byte[rax] lea rsi,[rax+1] push STD_OUTPUT SYS_WRITE pop rax rdi syscall lea esi,[stack_alignment_fault.message] mov edx,stack_alignment_fault - stack_alignment_fault.message push STD_OUTPUT SYS_WRITE pop rax rdi syscall and rsp,not 0xf jmp quit end if shaders: virtual at 0 fragment_shader:: db "varying vec4 d,u;" ; d = texture position, u = color db "float r(vec2 p){" ; PRNG db "return fract(cos(p.x*log(2.)+p.y*log(3.))*exp(8.));" db "}" db "float n(vec2 p){" ; noise db "vec2 i=floor(p),s=smoothstep(0.,1.,fract(p)),z=vec2(1,0);" db "float j=r(i),k=r(i+z),l=r(i+z.yx),m=r(i+z.xx);" ; corners at jklm db "return mix(j,k,s.x)+(l-j+(j-k-l+m)*s.x)*s.y;" db "}" db "float m(vec4 p){" ; fractal brownian motion db "float a=.5,f=2.,v=0.;" db "do{" db "v+=a*n(f*p.xy);a*=.5;f+=f;" db "}while(f<99.);" db "return v;" db "}" db "void main(){" db "gl_FragColor=mix(u*0.,u,m(d-d.w+m(d+d.w+m(d))));" db "}",0 fragment_shader_len = $ end virtual encode fragment_shader:, fragment_shader_len dw GL_FRAGMENT_SHADER virtual at 0 vertex_shader:: shader_faces = 6 shader_sides = 4 shader_period = 1 shl 24 - 1 db "varying vec4 d,u;" ; d = texture position, u = color db "vec3 s(vec3 p,vec3 v,float a){" ; spin point p around vector v by angle 2a db "vec3 q=normalize(v)*sin(a);" ; quaternion db "return p+2.*cross(q,cross(q,p)+cos(a)*p);" db "}" db "void main(){" db "u=gl_Vertex;" ; u.x = time (0-shader_period), u.y = point (0-23), u.z = width, u.w = height db "float b=4.,p=mod(u.y,b),f=(u.y-p)/b,t=u.x/4096.,s=sin(t),c=cos(t*.7),r=fract(t),k=atan(1.);" db "vec3 z=vec3(0,0,1),v=s(vec3(1,1,1.+.41*smoothstep(1.,3.,mix(b,r*8.,sign(.5-r)))),z,p*k);" db "d=vec4(v,t+f);" db "v=s(s(s(s(s(v,z,(smoothstep(1.,7.,r*8.)+mod(t-r,b))*k),z.zxx,floor(.8+f/b)*k),z,f*k),vec3(s,c,c+s),5.*c*s)-z,z.xzx,s/(c+1.2));" db "gl_Position=vec4(v.xy*min(vec2(u.w/u.z,u.z/u.w),z.zz)*5.,-v.z,10.-v.z);" ; translate: -10, projection: near = 5, far = inf db "u=vec4(1,.8,.3,1);u=f<2.?u:f<b?u.grba:u.brga;" ; colour swizzle db "u=mod(f,2.)<.5?u:u.rbga;" db "}",0 vertex_shader_len = $ end virtual encode vertex_shader:, vertex_shader_len dw GL_VERTEX_SHADER shader_count = 2 if fragment_shader_len > vertex_shader_len shader_length = fragment_shader_len else shader_length = vertex_shader_len end if if check_errors hex_table db '0123456789abcdef' end if framed_width dd x_res framed_height dd y_res hashes: match =,funcs,functions { irp f,funcs \{ if used f hash = 5381 virtual at 0 db \`f while % <= $ load c byte from % - 1 hash = (hash * 33 + c) and 0xffffffff end while end virtual label f qword at $ + $ - hashes dd hash end if \}} proc_count = ($ - hashes) shr 2 procs: interpreter: db '/lib64/ld-linux-x86-64.so.2',0 GL db 'libGL.so',0 SDL db 'libSDL.so' rb proc_count * 4 + procs - $ current_width rd 1 current_height rd 1 SDL_Event rb 4 SDL_width rd 1 SDL_key rb 0 SDL_height rd 1 shader_text rb shader_length if check_errors log_buffer rb buffer_size end if It fits into 0x664 bytes, so two bytes to spare. It has one user control. Press f to toggle between full screen and windowed. Press any other key to exit. The cube resizes to fit into the window frame. The window frame can be resized. The cube has a billowing smoke effect surface. The faces periodically disassemble themselves and recombine into a new arrangement.
|
|||||||||||||||||||
![]() |
|
redsock 25 Jan 2023, 20:58
This looks cool, thank your colleague for sharing it here.
I was unable to get it to work however, perhaps a version issue? Not necessarily easy to debug of course ![]() Using gdb and poking around, it is segfaulting on the Code: mov ecx,[rbx+gnu_hash.bucket_count] ; rcx = bucket count More information on the binary state on this machine: Code: > ls -la test -rwxr-xr-x 1 user users 1636 Jan 26 06:53 test > file ./test ./test: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, stripped > ldd ./test linux-vdso.so.1 (0x00007fff981ce000) libGL.so => /usr/lib64/libGL.so (0x00007fdb159c0000) libSDL.so => /usr/lib64/libSDL.so (0x00007fdb15728000) libGLX.so.0 => /usr/lib64/libGLX.so.0 (0x00007fdb154f7000) libGLdispatch.so.0 => /usr/lib64/libGLdispatch.so.0 (0x00007fdb15241000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fdb1501e000) libc.so.6 => /lib64/libc.so.6 (0x00007fdb14c29000) libasound.so.2 => /usr/lib64/libasound.so.2 (0x00007fdb14927000) libm.so.6 => /lib64/libm.so.6 (0x00007fdb145dc000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fdb143d8000) libpulse-simple.so.0 => /usr/lib64/libpulse-simple.so.0 (0x00007fdb141d3000) libpulse.so.0 => /usr/lib64/libpulse.so.0 (0x00007fdb13f80000) libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007fdb13c3f000) libXext.so.6 => /usr/lib64/libXext.so.6 (0x00007fdb13a2d000) libXrandr.so.2 => /usr/lib64/libXrandr.so.2 (0x00007fdb13822000) /lib64/ld-linux-x86-64.so.2 (0x00007fdb15c4b000) libpulsecommon-15.0.so => /usr/lib64/pulseaudio/libpulsecommon-15.0.so (0x00007fdb13599000) libdbus-1.so.3 => /usr/lib64/libdbus-1.so.3 (0x00007fdb13347000) libxcb.so.1 => /usr/lib64/libxcb.so.1 (0x00007fdb1311e000) libXrender.so.1 => /usr/lib64/libXrender.so.1 (0x00007fdb12f13000) librt.so.1 => /lib64/librt.so.1 (0x00007fdb12d0a000) libsndfile.so.1 => /usr/lib64/libsndfile.so.1 (0x00007fdb12a8e000) libsystemd.so.0 => /usr/lib64/libsystemd.so.0 (0x00007fdb15d53000) libXau.so.6 => /usr/lib64/libXau.so.6 (0x00007fdb1288a000) libFLAC.so.8 => /usr/lib64/libFLAC.so.8 (0x00007fdb1264d000) libogg.so.0 => /usr/lib64/libogg.so.0 (0x00007fdb12446000) libvorbis.so.0 => /usr/lib64/libvorbis.so.0 (0x00007fdb12219000) libvorbisenc.so.2 => /usr/lib64/libvorbisenc.so.2 (0x00007fdb11f70000) libspeex.so.1 => /usr/lib64/libspeex.so.1 (0x00007fdb11d55000) liblzma.so.5 => /usr/lib64/liblzma.so.5 (0x00007fdb11b1b000) libzstd.so.1 => /usr/lib64/libzstd.so.1 (0x00007fdb117eb000) liblz4.so.1 => /usr/lib64/liblz4.so.1 (0x00007fdb115ca000) libcap.so.2 => /usr/lib64/libcap.so.2 (0x00007fdb113c0000) libgcrypt.so.20 => /usr/lib64/libgcrypt.so.20 (0x00007fdb11083000) libgpg-error.so.0 => /usr/lib64/libgpg-error.so.0 (0x00007fdb10e5f000) > objdump -dx -M intel ./test ./test: file format elf64-x86-64 ./test architecture: i386:x86-64, flags 0x00000102: EXEC_P, D_PAGED start address 0x0000000000010107 Program Header: DYNAMIC off 0x00000000000000b0 vaddr 0x00000000000100b0 paddr 0x00000000000100b0 align 2**0 filesz 0x0000000000000050 memsz 0x0000000000000050 flags --- LOAD off 0x0000000000000000 vaddr 0x0000000000010000 paddr 0x0000000000010000 align 2**12 filesz 0x0000000000000664 memsz 0x00000000000008f7 flags rwx Sections: Idx Name Size VMA LMA File off Algn SYMBOL TABLE: no symbols > cat /etc/os-release NAME="openSUSE Leap" VERSION="15.4" ID="opensuse-leap" ID_LIKE="suse opensuse" VERSION_ID="15.4" PRETTY_NAME="openSUSE Leap 15.4" ANSI_COLOR="0;32" CPE_NAME="cpe:/o:opensuse:leap:15.4" BUG_REPORT_URL="https://bugs.opensuse.org" HOME_URL="https://www.opensuse.org/" DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap" LOGO="distributor-logo-Leap" |
|||
![]() |
|
revolution 26 Jan 2023, 03:12
Your libraries are in a different path.
Code: libGL.so => /usr/lib/x86_64-linux-gnu/libGL.so (0x00007f9485dd8000) libSDL.so => /usr/lib/x86_64-linux-gnu/libSDL.so (0x00007f9485b3f000) Code: NAME="Linux Mint" VERSION="18.3 (Sylvia)" ![]() Of course to make the code small far too many dangerous assumptions are made. So it isn't really surprising that the code is fragile. |
|||
![]() |
|
revolution 26 Jan 2023, 03:48
Here is a version without the shrink wrapped trickery.
Code: check_errors = 0 ; set to 1 to compile with error checking x_res = 533 ; default start width y_res = 300 ; default start height buffer_size = 2000 ; make enough space to capture error text from the library ;Versions ;OpenGL GLSL ;2.0 1.10 <--- this code ;2.1 1.20 ;3.0 1.30 ;3.1 1.40 ;3.2 1.50 ;3.3 3.30 ;/usr/include/SDL/SDL.h ;/usr/include/SDL/SDL_video.h ;/usr/include/SDL/SDL_events.h SDL_INIT_VIDEO = 0x20 SDL_OPENGL = 0x00000002 SDL_RESIZABLE = 0x00000010 SDL_FULLSCREEN = 0x80000000 SDL_FULLSCREEN_BIT = 31 SDL_KEYDOWN = 2 SDL_QUIT = 12 SDL_VIDEORESIZE = 16 ;/usr/include/GL/gl.h ;/usr/include/SDL/SDL_opengl.h GL_LINE_LOOP = 0x0002 GL_TRIANGLES = 0x0004 GL_TRIANGLE_STRIP = 0x0005 GL_TRIANGLE_FAN = 0x0006 GL_POLYGON = 0x0009 GL_FRONT = 0x0404 GL_BACK = 0x0405 GL_FRONT_AND_BACK = 0x0408 GL_CW = 0x0900 GL_CCW = 0x0901 GL_CULL_FACE = 0x0b44 GL_DEPTH_TEST = 0x0b71 GL_VIEWPORT = 0x0ba2 GL_MODELVIEW = 0x1700 GL_PROJECTION = 0x1701 GL_POINT = 0x1b00 GL_LINE = 0x1b01 GL_FILL = 0x1b02 GL_FRAGMENT_SHADER = 0x8b30 GL_VERTEX_SHADER = 0x8b31 GL_COMPILE_STATUS = 0x8b81 GL_VALIDATE_STATUS = 0x8b83 GL_DEPTH_BUFFER_BIT = 0x00000100 GL_COLOR_BUFFER_BIT = 0x00004000 GL_NO_ERROR = 0 GL_FALSE = 0 SYS_WRITE = 1 SYS_EXECVE = 59 SYS_EXIT = 60 STD_OUTPUT = 1 DT_NULL = 0 DT_NEEDED = 1 DT_STRTAB = 5 DT_SYMTAB = 6 DT_RELA = 7 DT_RELASZ = 8 DT_RELAENT = 9 DT_STRSZ = 10 DT_SYMENT = 11 DT_BIND_NOW = 24 DT_FLAGS = 30 DT_FLAGS_1 = 0x6ffffffb STB_GLOBAL = 1 STT_FUNC = 2 R_X86_64_64 = 1 DF_BIND_NOW = 0x00000008 DF_1_NOW = 0x00000001 DF_1_PIE = 0x08000000 macro encode text, length { bits = 0 accum = 0 offset = 0 while offset < length load c byte from text+offset if c = char_escape | c >= 0x7f display c shr 6 + '0', c shr 3 and 7 + '0', c and 7 + '0', 10 err ; bad character end if if (c >= 0x40 & c <= 0x5e) | c <= 0x1f store byte c + 0x20 at text+offset offset = offset - 1 c = char_escape end if if c >= 0x5f c = c - 0x3f else c = c - 0x20 end if accum = accum + c shl bits bits = bits + 6 if bits > 18 dw accum and 0xffff db accum shr 16 bits = 0 accum = 0 end if offset = offset + 1 end while if bits > 12 dw accum and 0xffff db accum shr 16 else if bits > 6 dw accum else if bits > 0 db accum end if } char_escape = '`' ; for uppercase and control characters functions equ macro invoke proc, [arg] { common regr equ rdi, rsi, rdx, rcx, r8, r9, -, - rege equ edi, esi, edx, ecx, r8d, r9d, -, - if ~ arg eq forward match rreg =, shiftr =| ereg =, shifte, regr | rege \{ regr equ shiftr rege equ shifte if arg eqtype 0 & 0 = arg xor ereg, ereg else if arg eqtype 0 & 0x80 > arg & -0x80 <= arg push arg pop rreg else if arg eqtype 0 & 1 shl 32 > arg & 0 <= arg mov ereg, arg else if ~ rreg eq arg if arg in <rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp> push arg pop rreg else mov rreg, arg end if end if \} common end if if check_errors local .proc_name, .skip_proc_name test spl,0xf lea rax,[.proc_name] jnz stack_alignment_fault jmp .skip_proc_name .proc_name: db .skip_proc_name - .proc_name - 1, `proc .skip_proc_name: end if call [proc] found equ 0 match a =proc b,x functions y \{ found equ 1 \} match =0, found \{ functions equ functions, proc \} } ; invoke with error check macro einvoke proc, [arg] { common local .okay, .proc_name invoke proc,arg if check_errors invoke glGetError assert GL_NO_ERROR = 0 test rax,rax jz .okay push rax mov edx,.okay - .proc_name lea esi,[.proc_name] push STD_OUTPUT SYS_WRITE pop rax rdi syscall pop rax jmp error .proc_name: db `proc,10 .okay: end if } ; invoke with return value check macro rinvoke proc, [arg] { common local .okay, .proc_name invoke proc,arg if check_errors test rax,rax jnz .okay push rax mov edx,.okay - .proc_name lea esi,[.proc_name] push STD_OUTPUT SYS_WRITE pop rax rdi syscall pop rax jmp error .proc_name: db `proc,10 .okay: end if } virtual org 0 struc r_debug { .r_version rq 1 ; version number for this protocol .r_map rq 1 ; head of the chain of loaded objects .r_brk rq 1 ; breakpoint for debugger to monitor .so mapping changes .r_state rq 1 ; object mapping state .r_ldbase rq 1 ; base address the linker is loaded at }r_debug r_debug org 0 struc link_map { .l_addr rq 1 ; library load address .l_name rq 1 ; file name of library .l_ld rq 1 ; dynamic section of library .l_next rq 1 ; next in chain .l_prev rq 1 ; previous in chain }link_map link_map org 0 struc gnu_hash { .bucket_count rd 1 .sumbol_offset rd 1 .bloom_size rd 1 .bloom_shift rd 1 .bucket_list rb 0 }gnu_hash gnu_hash org 0 struc Elf64_Sym { .st_name rd 1 .st_info rb 1 .st_other rb 1 .st_shndx rw 1 .st_value rq 1 .st_size rq 1 }Elf64_Sym Elf64_Sym sizeof.Elf64_Sym = $ end virtual format ELF64 executable 3 at 0x10000 entry begin segment gnustack segment executable begin: invoke SDL_Init,SDL_INIT_VIDEO if check_errors test rax,rax jnz error end if push SDL_OPENGL or SDL_RESIZABLE pop r13 call set_video rinvoke glCreateProgram xchg r15,rax ; r15 = program push rax ; stack align mov esi,shaders push shader_count pop rcx .next_shader: push rcx lea edi,[shader_text] push rdi .next_quad: lodsd dec esi shl eax,8 mov cl,4 .next_byte: dec cl js .next_quad ror eax,6 shr al,2 add al,0x20 cmp al,0x3f jbe .byte_ready add al,0x5f-0x40 .byte_ready: xor al,ch ; apply escape mov ch,0x20 ; enable escape mode cmp al,char_escape jz .next_byte stosb mov ch,0 ; disable escape mode cmp al,0 jnz .next_byte sub ecx,1 sbb esi,ecx lodsw ; load shader type movzx edi,ax pop rax push rsi rax rinvoke glCreateShader,rdi xchg rbx,rax ; rbx = shader einvoke glShaderSource,rbx,1,rsp,0 einvoke glCompileShader,rbx if check_errors push rax ; stack align call shader_log push GL_FALSE invoke glGetShaderiv,rbx,GL_COMPILE_STATUS,rsp pop rax cmp rax,GL_FALSE pop rax ; stack align jz error end if einvoke glAttachShader,r15,rbx pop rax rsi rcx if check_errors dec cl jnz .next_shader else loop .next_shader end if pop rax ; stack align einvoke glLinkProgram,r15 if check_errors invoke glValidateProgram,r15 push rax ; stack align call program_log push GL_FALSE invoke glGetProgramiv,r15,GL_VALIDATE_STATUS,rsp pop rax cmp rax,GL_FALSE pop rax ; stack align jz error end if einvoke glUseProgram,r15 rdtsc xchg r15,rax ; r15 = time offset invoke glEnable,GL_DEPTH_TEST .animation_loop: einvoke glClear,GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT invoke SDL_GetTicks add rax,r15 and eax,shader_period push qword[current_width] rax ; w = height, z = width, y = point, x = time mov bl,shader_faces .face_loop: invoke glBegin,GL_POLYGON mov bh,shader_sides .vertex_loop: invoke glVertex4iv,rsp inc dword[rsp+4] dec bh jnz .vertex_loop einvoke glEnd dec bl jnz .face_loop pop rax rax invoke SDL_GL_SwapBuffers .get_event: lea edi,[SDL_Event] invoke SDL_PollEvent,rdi test eax,eax jz .animation_loop mov al,[SDL_Event] cmp al,SDL_VIDEORESIZE jne .not_resized push qword[SDL_width] pop qword[framed_width] .set_frame: call set_video mov edx,[current_width] mov ecx,[current_height] invoke glViewport,0,0,rdx,rcx jmp .get_event .not_resized: cmp al,SDL_QUIT je quit cmp al,SDL_KEYDOWN jne .get_event btc r13,SDL_FULLSCREEN_BIT cmp [SDL_key],'f' je .set_frame quit: invoke SDL_Quit xor edi,edi kill: push SYS_EXIT pop rax syscall set_video: push rax ; stack align mov edi,[framed_width] mov esi,[framed_height] assert SDL_FULLSCREEN_BIT = 31 test r13d,r13d setns bl jns .set invoke SDL_ListModes,0,r13 if check_errors cmp rax,0 jle error end if mov rax,[rax] movzx edi,word[rax+4] movzx esi,word[rax+6] .set: mov [current_width],edi mov [current_height],esi rinvoke SDL_SetVideoMode,rdi,rsi,0,r13 movzx edi,bl invoke SDL_ShowCursor,rdi pop rax ; stack align ret if check_errors error: sub rsp,20 mov rsi,rsp push 15 pop rcx .next_nibble: mov edx,eax and edx,0xf mov dl,[hex_table+rdx] mov [rsi+rcx],dl shr rax,4 dec ecx jns .next_nibble mov byte[rsi+16],10 push STD_OUTPUT SYS_WRITE 17 pop rdx rax rdi syscall add rsp,20 jmp quit program_log: lea edx,[log_buffer] lea ecx,[rdx+8] push 0 pop qword[rdx] invoke glGetProgramInfoLog,r15,buffer_size,rdx,rcx jmp log shader_log: lea edx,[log_buffer] lea ecx,[rdx+8] push 0 pop qword[rdx] invoke glGetShaderInfoLog,rbx,buffer_size,rdx,rcx log: mov rdx,qword[log_buffer] test rdx,rdx jz .ret lea esi,[log_buffer+8] push STD_OUTPUT SYS_WRITE pop rax rdi syscall .ret: ret stack_alignment_fault.message: db ': Stack alignment error',10 stack_alignment_fault: movzx edx,byte[rax] lea rsi,[rax+1] push STD_OUTPUT SYS_WRITE pop rax rdi syscall lea esi,[stack_alignment_fault.message] mov edx,stack_alignment_fault - stack_alignment_fault.message push STD_OUTPUT SYS_WRITE pop rax rdi syscall and rsp,not 0xf jmp quit end if macro Elf64_Sym name,value,size,bind,type,other,shndx { dd name+0 db (bind+0) shl 4 + (type+0) db other+0 dw shndx+0 dq value+0 dq size+0 } macro Elf64_Rela offset,symbol,type,addend { dq rva offset+0 dq (symbol+0) shl 32 + (type+0) dq addend+0 } virtual at 0 Elf64_Sym sizeof.Elf64_Sym = $ Elf64_Rela sizeof.Elf64_Rela = $ - sizeof.Elf64_Sym end virtual segment dynamic readable dq DT_NEEDED,_sdl - strtab dq DT_NEEDED,_gl - strtab dq DT_STRTAB,rva strtab dq DT_STRSZ,strsz dq DT_SYMTAB,rva symtab dq DT_SYMENT,sizeof.Elf64_Sym dq DT_RELA,rva rela dq DT_RELASZ,relasz dq DT_RELAENT,sizeof.Elf64_Rela dq DT_BIND_NOW,1 dq DT_FLAGS,DF_BIND_NOW dq DT_FLAGS_1,DF_1_NOW or DF_1_PIE dq DT_NULL,0 symtab: Elf64_Sym match =,funcs,functions { irp f,funcs \{ if used f Elf64_Sym _\#f - strtab,0,0,STB_GLOBAL,STT_FUNC,0,0 end if \}} rela: num = 1 match =,funcs,functions { irp f,funcs \{ if used f Elf64_Rela f,num,R_X86_64_64 num = num + 1 end if \}} relasz = $ - rela match =,funcs,functions { irp f,funcs \{ if used f f rq 1 end if \}} segment interpreter readable db '/lib64/ld-linux-x86-64.so.2' strtab: db 0 _sdl db 'libSDL-1.2.so.0',0 _gl db 'libGL.so.1',0 match =,funcs,functions { irp f,funcs \{ if used f _\#f db \`f,0 end if \}} strsz = $ - strtab segment readable writeable shaders: virtual at 0 fragment_shader:: db "varying vec4 d,u;" ; d = texture position, u = color db "float r(vec2 p){" ; PRNG db "return fract(cos(p.x*log(2.)+p.y*log(3.))*exp(8.));" db "}" db "float n(vec2 p){" ; noise db "vec2 i=floor(p),s=smoothstep(0.,1.,fract(p)),z=vec2(1,0);" db "float j=r(i),k=r(i+z),l=r(i+z.yx),m=r(i+z.xx);" ; corners at jklm db "return mix(j,k,s.x)+(l-j+(j-k-l+m)*s.x)*s.y;" db "}" db "float m(vec4 p){" ; fractal brownian motion db "float a=.5,f=2.,v=0.;" db "do{" db "v+=a*n(f*p.xy);a*=.5;f+=f;" db "}while(f<99.);" db "return v;" db "}" db "void main(){" db "gl_FragColor=mix(u*0.,u,m(d-d.w+m(d+d.w+m(d))));" db "}",0 fragment_shader_len = $ end virtual encode fragment_shader:, fragment_shader_len dw GL_FRAGMENT_SHADER virtual at 0 vertex_shader:: shader_faces = 6 shader_sides = 4 shader_period = 1 shl 24 - 1 db "varying vec4 d,u;" ; d = texture position, u = color db "vec3 s(vec3 p,vec3 v,float a){" ; spin point p around vector v by angle 2a db "vec3 q=normalize(v)*sin(a);" ; quaternion db "return p+2.*cross(q,cross(q,p)+cos(a)*p);" db "}" db "void main(){" db "u=gl_Vertex;" ; u.x = time (0-shader_period), u.y = point (0-23), u.z = width, u.w = height db "float b=4.,p=mod(u.y,b),f=(u.y-p)/b,t=u.x/4096.,s=sin(t),c=cos(t*.7),r=fract(t),k=atan(1.);" db "vec3 z=vec3(0,0,1),v=s(vec3(1,1,1.+.41*smoothstep(1.,3.,mix(b,r*8.,sign(.5-r)))),z,p*k);" db "d=vec4(v,t+f);" db "v=s(s(s(s(s(v,z,(smoothstep(1.,7.,r*8.)+mod(t-r,b))*k),z.zxx,floor(.8+f/b)*k),z,f*k),vec3(s,c,c+s),5.*c*s)-z,z.xzx,s/(c+1.2));" db "gl_Position=vec4(v.xy*min(vec2(u.w/u.z,u.z/u.w),z.zz)*5.,-v.z,10.-v.z);" ; translate: -10, projection: near = 5, far = inf db "u=vec4(1,.8,.3,1);u=f<2.?u:f<b?u.grba:u.brga;" ; colour swizzle db "u=mod(f,2.)<.5?u:u.rbga;" db "}",0 vertex_shader_len = $ end virtual encode vertex_shader:, vertex_shader_len dw GL_VERTEX_SHADER shader_count = 2 if fragment_shader_len > vertex_shader_len shader_length = fragment_shader_len else shader_length = vertex_shader_len end if if check_errors hex_table db '0123456789abcdef' end if framed_width dd x_res framed_height dd y_res current_width rd 1 current_height rd 1 SDL_Event rb 4 SDL_width rd 1 SDL_key rb 0 SDL_height rd 1 shader_text rb shader_length if check_errors log_buffer rb buffer_size end if |
|||
![]() |
|
FlierMate11 26 Jan 2023, 08:22
I tried it and your latest code works! It is cool.
The first version is 1636 bytes (not 666 bytes) when compiled on Debian 11.6 here, like what @redsock has pointed out, it ended with "segmentation fault". Yes, the second version is twice the size of first version.
|
|||||||||||||||||||
![]() |
|
revolution 26 Jan 2023, 08:27
It is 0x664 bytes. That is a hex number.
|
|||
![]() |
|
revolution 26 Jan 2023, 08:30
FlierMate11 wrote: The first version ... ended with "segmentation fault". So the later Linuxes are compiling the libraries differently. Good to know. |
|||
![]() |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.