Ifjoncabb kollégákkal beszélgetve szóba került, hogy még nem láttak assembly kódot, ezért gondoltam mutatok nekik, mégiscsak tudják mi fán terem :)
Az volt az ötletem, hogy nézzünk meg egy HelloWorldöt asm-ben meg javaban, hogy lássák tényleg ilyen ilyen obskúrus izék lesznek abból amit ők írkálnak. Na a Javaról hamar letettem, hogy gdb-vel nézegessek egy System.out.println() -t, próbáljuk meg C-ben, de itt is ráballagtam a banánhéjra.
Az asm progi:
.global _start
.text
_start:
	mov $1, %rax
	mov $1, %rdi
	mov $message, %rsi
	mov $13, %rdx
	syscall
	mov $60, %rax
	xor %rdi, %rdi
	syscall
.data
message:
	.ascii "Hello World!\n"
A C progi:
#include <stdio.h>
int main(void) {
	puts("Hello World!\n");
	return 0;
}
gcc -Wall -g hello.c -o helloc
gdb helloc
aztán breakpoint a puts-ra és had szaladjon!
...
Reading symbols from helloc...
(gdb) b puts
Breakpoint 1 at 0x1050
(gdb) r
Starting program: /sandbox/asm/helloc 
This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) 
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, __GI__IO_puts (str=0x555555556004 "Hello World!\n") at ./libio/ioputs.c:33
33	./libio/ioputs.c: No such file or directory.
(gdb) disassemble
Dump of assembler code for function __GI__IO_puts:
Address range 0x7ffff7c7af40 to 0x7ffff7c7b166:
=> 0x00007ffff7c7af40 <+0>:	endbr64
   0x00007ffff7c7af44 <+4>:	push   %r14
   0x00007ffff7c7af46 <+6>:	push   %r13
   0x00007ffff7c7af48 <+8>:	push   %r12
   0x00007ffff7c7af4a <+10>:	push   %rbp
   0x00007ffff7c7af4b <+11>:	mov    %rdi,%rbp
   0x00007ffff7c7af4e <+14>:	push   %rbx
   0x00007ffff7c7af4f <+15>:	sub    $0x10,%rsp
   0x00007ffff7c7af53 <+19>:	call   0x7ffff7c224c0 <*ABS*+0xa6ff0@plt>
   0x00007ffff7c7af58 <+24>:	mov    0x17aec1(%rip),%r13        # 0x7ffff7df5e20
   0x00007ffff7c7af5f <+31>:	mov    %rax,%rbx
   0x00007ffff7c7af62 <+34>:	mov    0x0(%r13),%r12
   0x00007ffff7c7af66 <+38>:	testl  $0x8000,(%r12)
   0x00007ffff7c7af6e <+46>:	je     0x7ffff7c7b040 <__GI__IO_puts+256>
   0x00007ffff7c7af74 <+52>:	mov    %r12,%rdi
   0x00007ffff7c7af77 <+55>:	mov    0xc0(%rdi),%eax
   0x00007ffff7c7af7d <+61>:	test   %eax,%eax
   0x00007ffff7c7af7f <+63>:	jne    0x7ffff7c7b096 <__GI__IO_puts+342>
   0x00007ffff7c7af85 <+69>:	movl   $0xffffffff,0xc0(%rdi)
   0x00007ffff7c7af8f <+79>:	mov    0xd8(%rdi),%r14
   0x00007ffff7c7af96 <+86>:	lea    0x177d63(%rip),%rdx        # 0x7ffff7df2d00 <_IO_printf_buffer_as_file_jumps>
...
Nyilván van a glibc-ben egy csomó más fontos sallang is, de azt furcsállom, hogy egy darab kernel hívás (syscall vagy call 0x80) nincs benne. Persze máshol biztos van, csak így, hogy kb. 0 az átfedés a két kód között, nem túl szemléletes :)
Segítsetek kérlek mit, hogy írjak másként, hogy összehasonlítható legyen?
Köszi!
- 886 megtekintés
 
Hozzászólások
(Szerintem a Java byte code-t akartad mutatni esetleg, nem a jvm disassembly-t. https://stackoverflow.com/questions/30928786/how-do-i-check-assembly-ou…)
- A hozzászóláshoz be kell jelentkezni
 
Azért is vetettem el a Java-t mert ott már első blikkre is nagyon macerásnak tűnt megtalálni az assembly-t de kösz a linket, hasznos!
- A hozzászóláshoz be kell jelentkezni
 
Nyilván nem fogsz itt syscallt látni, hiszen magát a kernelt a glibc hívja meg, miután platformspecifikus módon implementálja a printf()-et, meg minden más libc függvényt. Ezek az absztrakciós rétegek már csak ilyenek, ez az ára a hordozhatóságnak.
Például a puts belső implementációja is ilyen:
https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/ioputs.c;h=7f719…
Ez ugye láthatólag a belső _IO_sputn-t hívja meg.
Az meg egy makró: https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/libioP.h;h=a83a4…
Ami megint csak egy makró: https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/libioP.h;h=a83a4…
Nem olyan egyszerű ám a libc, mint az ember gondolná.
- A hozzászóláshoz be kell jelentkezni
 
- A hozzászóláshoz be kell jelentkezni
 
Köszi!
- A hozzászóláshoz be kell jelentkezni
 
Az a baj, hogy szép, hogy a musl soványabb, és nem olyan elhízott, mint a glibc, de sajnos van bőven szoftver, ami glibc nélkül nem fog menni. Az is igaz, hogy bloat a glibc, de azért attól is függ, hogy mihez képest nézzük. Ha a Javához, meg a hőn utált Rust-odhoz képest nézzük, azokhoz képest akár soványkának is lehetne nevezni.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
 
a hőn utált Rust-odhoz képest nézzükÉn nem utálom a Rust-ot. Nem a kedvenc nyelvem, látom a hosszútávú buktatóit, de nem utálom. Amit utálok, az a sok nagypofájú balfasz Rustafári, akik azt hiszik, ők szarták a spanyolviaszt és mindenkinek megpróbálnak beugatni, ha kritikát merészel megfogalmazni az imádott nyelvükkel kapcsolatban. Építő jellegű kritika nélkül sose fog beérni, úgyhogy pont a hypevonatos Rustafárik miatt fog megbukni ez a nyelv.
azokhoz képest akár soványkának is lehetne nevezni.Inkább a többi libc-hez kell mérni, pl. MUSL, vagy uClibc vagy newlib.
- A hozzászóláshoz be kell jelentkezni
 
- A hozzászóláshoz be kell jelentkezni
 
Simán kicserélve nem lett jó.
pentike@5CG3464HPJ:~/sandbox/asm$ cat hello.c
#include <stdio.h>
int main(void) {
	write(1,"Hello World!\n",13);
	return 0;
}
pentike@5CG3464HPJ:~/sandbox/asm$ gcc -Wall hello.c -o helloc --static
hello.c: In function ‘main’:
hello.c:4:9: warning: implicit declaration of function ‘write’; did you mean ‘fwrite’? [-Wimplicit-function-declaration]
    4 |         write(1,"Hello World!\n",13);
      |         ^~~~~
      |         fwrite
- A hozzászóláshoz be kell jelentkezni
 
üdv.
Az unistd.h-t be kell fűzni a forráskódba.
Szerk: és az stdio.h nem kell
/* bocs az esetleges helyesirasi hidakert */
- A hozzászóláshoz be kell jelentkezni
 
Viszont az unistd.h behúzása magával vonhatja impliciten az stdio.h-t a szabvány szerint:
Inclusion of the <unistd.h> header may make visible all symbols from the headers <fcntl.h>, <stddef.h>, <stdint.h>, and <stdio.h>.
- A hozzászóláshoz be kell jelentkezni
 
(May = megteheti, de nem köteles, implementációfüggő)
- A hozzászóláshoz be kell jelentkezni
 
Pörfikt! Köszi!
- A hozzászóláshoz be kell jelentkezni
 
A többiek majd javítanak ha szerintük rosszat mondok, de szerintem ott rontottad el, hogy túl magas szintű eljárásal akartál valamit bemutatni. Ha puts, vagy printf vagy hasonló, akkor az már a "nagy" C-függvénykönyvtár része (man, 3. fejezet) - ilyen feladatra egyértelműen sokkal jobb a rendszerhívásokhoz sokkal közelebbi példákat használó eszköz - ezért is használhatóbb a fenti write-os példa (elvben ugye a write az rendszerhívás - system call - "rendes" rendszerben a man 2. fejezet.) A man-t amúgy se hátrány ilyen esetben lapozgatni, elvben legalábbis ildomos lenne ilyeneket leírni, ami itt is kiderült, hogy stdio-t vagy unistd-t kell-e inkludálni.
- A hozzászóláshoz be kell jelentkezni
 
Igazad van!
Nem mozgok otthonosan c-ben meg asm-ben ezért ezért a kisebb buktatókban is könnyen pofára tudok esni. :)
- A hozzászóláshoz be kell jelentkezni
 
Ajánlom a https://godbolt.org/ oldalt. A bal oldali panelbe beírod a C kódot, jobb oldalon meg kb. valós időben látod az assembly-t, az egymásnak megfelelő részeket azonos színnel kiemelve. Választhatsz egy csomó féle nyelvet és fordítóprogramot.
- A hozzászóláshoz be kell jelentkezni
 
Off: Az biztos, hogy a glibc tele van felesleges bonyolításokkal, de azért talán árnyalja a kérdést, ha megnézzük ezt: https://man7.org/linux/man-pages/man3/fopencookie.3.html
Vagyis saját rutinokat használhatunk FILE-ként. (BSD-ben funopen)
Egy számmal közelebb vagyunk a kernelhez a `write` használatával: https://man7.org/linux/man-pages/man2/write.2.html
- A hozzászóláshoz be kell jelentkezni
 
graal vm-mel lehet binárisra fordítani Java programot. Indulás teljesítmény okokból szokták használni például. Hogy a generált ASM milyen, meg hogy hogy kell megnézni arról fogalmam sincsen sajnos. (Subscribe)
- A hozzászóláshoz be kell jelentkezni
 
Húbakker, tényleg! Hogy ez nem jutott eszembe, pedig még meséltem is a graalvm-ről a kollégáknak, hogy az nem bytekódra hanem gépi kódra fordít.
- A hozzászóláshoz be kell jelentkezni
 
Ha már assembly tanulás, és Linux a célrendszer, akkor én is ajánlok weboldalt:
"Share what you know. Learn what you don't."
- A hozzászóláshoz be kell jelentkezni
 
banánhélyra?
- A hozzászóláshoz be kell jelentkezni
 
akkor ezen most duplán elcsúsztam :) Javítva.
- A hozzászóláshoz be kell jelentkezni