Tonika: Own your social ties
5ttt.org2 pointsby ericbb1 comments
push rbp
mov rbp,rsp
lea rax,[rbp+0x10]
mov QWORD PTR [rbp+0x10],rax
Instead of passing the struct in registers (rdi, rsi, rdx) or passing a pointer to the object (pass by reference), the caller places the object on the stack and the callee knows where to find it just based on the type of the function (it's at [rbp+0x10]). push rbp
mov rbp,rsp
sub rsp,0x10
mov rax,rdi
mov rcx,rsi
mov rdx,rcx
mov QWORD PTR [rbp-0x10],rax
mov QWORD PTR [rbp-0x8],rdx
lea rax,[rbp-0x10]
mov QWORD PTR [rbp-0x10],rax
In that case, the struct was passed in via registers rdi, rsi (similar to tom_mellior's example) and subsequently copied to the stack (at [rbp-0x10] this time). #include <stdio.h>
#include <stdlib.h>
struct example { void *a, *b, *c; };
void foo(struct example x)
{
x.a = &x;
if (x.a != NULL) puts("In foo(), x.a is not NULL.");
}
int
main(void)
{
struct example x = { .a = NULL };
printf("sizeof(x): %lu bytes (%lu bits).\n", sizeof(x), 8 * sizeof(x));
foo(x);
if (x.a == NULL) puts("In main(), x.a is NULL.");
return 0;
} ff[x] = [atom[x] → x; T → ff[car[x]]]
S-expressions: (defun ff (x) (cond ((atom x) x) (T (ff (car x)))))
The semicolon and the infix arrow have the benefit of reducing the need for parentheses in that case. And you can avoid writing "defun" and "cond". odd 0 = False
odd n = even (n - 1)
even 0 = True
even n = odd (n - 1)
I think "rewriting system" is something similar. (I'm not an expert in this stuff so I'm providing hints for further reading more than anything else). $ cat test.c
void _start(void)
{
__asm__(
"movabsq $6278066737626506568,%rax\n\t"
"movq %rax,-32(%rsp)\n\t"
"movl $1684828783,-24(%rsp)\n\t"
"movw $10,-20(%rsp)\n\t"
"movq $1,%rax\n\t"
"movq $1,%rdi\n\t"
"leaq -32(%rsp),%rsi\n\t"
"movq $13,%rdx\n\t"
"syscall\n\t"
"movq $60,%rax\n\t"
"movq $0,%rdi\n\t"
"syscall");
}
$ gcc -nostdlib -static -Os -o test test.c && strip test && ls -lgG test
-rwxr-xr-x 1 864 Sep 28 14:22 test
864 bytes! :) $ cat test.c
static int sys_write(int fd, const void *buf, unsigned long n)
{
asm("mov $1,%rax; syscall");
}
static void sys_exit(int status)
{
asm("mov $60,%rax; syscall");
}
void _start(void)
{
char s[] = "Hello, World\n";
int r = sys_write(1, s, sizeof(s) - 1);
sys_exit(r == -1 ? 1 : 0);
}
$ gcc -nostdlib -static -o test test.c && ls -lgG test
-rwxr-xr-x 1 1480 Sep 28 11:47 test
More to the point of your question, if you want to see the effect you're looking for, I think you need to link to a libfoo.a library that includes some module.o that your program doesn't use. void free_circularly_linked_list(struct node *head)
{
struct node *a = head->next;
while (a != head) {
struct node *b = a->next;
free(a);
a = b;
}
free(head);
}
Great example, by the way!