Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C, ASM]Funkcje o zmiennej liczbie argumentów

Ostatnio zmodyfikowano 2013-08-22 14:01
Autor Wiadomość
Mrovqa
» 2013-08-04 16:15:46
Po prostu wrzucasz na stos odpowiednie parametry i zgodnie z konwencją cdecl czyścisz po wywołaniu (tj. usuwa je caller, nie callee). Nie wiem jak dokładnie wygląda stos w twojej funkcji, tj. czy będzie ramka stosu, inne dane - ogólnie - na co konkretnie będzie wskazywać esp i jaki będzie potrzebny offset do argumentów, ale można wykorzystać funkcje 'gołe' i tą pewność uzyskać :)
http://gynvael.coldwind.pl/​?id=14
P-89475
Brezniew
Temat założony przez niniejszego użytkownika
» 2013-08-04 17:17:21
Dopisałem do funkcji instrukcje %s, %c, i jak na razie działa, ale ale nie wiem ja zmienić wartość ESP ( usunąć argumenty ze stosu ). Oto kod:
C/C++
void puts( const char * s,...)
{
    byte state;
    word offset = 1;
    void * arg = & s;
    int i;
   
    for( state = 0; * s; s++ )
    {
        if( state == 0 )
        {
            if( * s == '%' ) state = 1;
            else put_c( * s, & con0 );
           
        }
        else
        {
            state = 0;
            switch( * s )
            {
            case '%':
                put_c( '%', & con0 );
                break;
            case 'c':
                put_c((( const char * ) arg )[ offset * 4 ], & con0 );
                offset = offset + 1;
                break;
            case 's':
                for( i = 0;(( const char ** ) arg )[ offset ][ i ]; i++ )
                     put_c((( const char ** ) arg )[ offset ][ i ], & con0 );
               
                offset = offset + 1;
                break;
            }
        }
    }
}

A co do stosu tu masz plik start.asm w którym jest utworzony stos dla kernel-a.


[BITS 32]
[SECTION .text]
EXTERN code, bss, end
mboot:                          ;header
dd 0x1BADB002                   ;signature
dd 0x10001                      ;flags
dd -(0x1BADB002 + 0x10001)      ;checksum
dd mboot
dd code
dd bss
dd end
dd start

GLOBAL start
start:
cli
lgdt [gdt_descr]
jmp _0
_0:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x18
mov ss, ax
mov esp, kernel_stack + 4096
EXTERN setup_gdt
call setup_gdt
lidt [idt_descr]
mov ax, 0x30
lldt ax
mov ax, 0x38
ltr ax
jmp _1
_1:
push dword L6
EXTERN start_kernel
push dword start_kernel
ret

L6:
jmp L6

[SECTION .data]
gdt_descr:                      ;header gdt
dw 0x7FF
dd gdt

GLOBAL gdt
gdt:                            ;global descriptor table
dd 0, 0                         ;0x00: null descriptor
dd 0x0000FFFF, 0x00CF9A00       ;0x08: kernel code descriptor
dd 0x0000FFFF, 0x00CF9200       ;0x10: kernel data descriptor
dd 0x0000FFFF, 0x00CF9200       ;0x18: kernel stack deskriptor
times 248 dd 0, 0               ;empty descriptors( 0x20 - 0x7F8 )

idt_descr:                      ;header idt
dw 0x7FF
dd idt

GLOBAL idt
idt:                            ;interrupt descriptor table
times 256 dd 0, 0               ;empty descriptors( 0x00 - 0x7F8 )

[SECTION .bss]
kernel_stack: resb 4096         ;kernel stack
P-89484
Mrovqa
» 2013-08-04 20:55:21
Tu chodzi o to, co będzie znajdowało się na stosie podczas wywołania tej funkcji, i to nie tylko dla kernela, ale każdej aplikacji. Najlepszym jednakże rozwiązaniem jest to, które podał Ci @Alueril i je radzę Tobie zastosować. To, co napisałem wcześniej, potraktuj jako ciekawostkę - zawsze przy okazji czegoś się nauczysz.
P-89494
Brezniew
Temat założony przez niniejszego użytkownika
» 2013-08-08 20:34:31
Postanowiłem użyć biblioteki stdarg.h do tego zacząłem budować gcc-cross ale przy kompilacji występuje ten błąd:
../gcc-4.6.3/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
...
...
configure: error: libmpfr not found or uses a different ABI (including static vs shared).
make: *** [configure-mpc] Błąd 1

co do tego że nieda się tego zaimplementować w samym c to ta biblioteka:
C/C++
#ifndef STDARG_H
#define STDARG_H

#ifndef _VA_LIST_DEFINED
#define _VA_LIST_DEFINED
typedef char * va_list;
#endif

#define _INTSIZEOF(n)    ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))

#define va_start(ap, v)  (ap = (va_list) &v + _INTSIZEOF(v))
#define va_arg(ap, t)    (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define va_end(ap)       (ap = (va_list) 0)

#endif

jak przewidywałem kod liczy adresy co 4 bajty to niewielka filozofia mój kod był poprawny, ale użyje tej biblioteki bo i tak planuje w przyszłości przenieść wszystkie biblioteki gnu w końcu to system to system pisany w oparciu o unix-a czyli system unixopodobny.
P-89744
pekfos
» 2013-08-09 10:59:08
Masz zainstalowane MPFR, MPC i GMP?
P-89769
Brezniew
Temat założony przez niniejszego użytkownika
» 2013-08-10 14:52:23
W systemie czy paczki src w paczce gcc?
Jak coś to ja używam Linux Ubuntu.
P-89899
pekfos
» 2013-08-10 16:45:35
Skompilowane i zainstalowane.
P-89914
Brezniew
Temat założony przez niniejszego użytkownika
» 2013-08-12 13:25:37
No chyba będą, w końcu są wymagane do gcc, a ja gcc mam w systemie jest on w końcu w pakiecie main systemu.
P-90084
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona