• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Odwołanie do części struktury przekazywanej w parametrze do funkcji przy użyciu wstawek assemblera

Object Storage Arubacloud
0 głosów
1,131 wizyt
pytanie zadane 31 stycznia 2016 w C i C++ przez jegor377 Stary wyjadacz (13,230 p.)
Siema,

Wiecie może jak odwołać się do adresu takiej zmiennej w strukturze (np. zmiennej 'a') mając adres struktury?

1 odpowiedź

+1 głos
odpowiedź 31 stycznia 2016 przez draghan VIP (106,230 p.)
wybrane 1 lutego 2016 przez jegor377
 
Najlepsza

Niekoniecznie musisz używać do tego ASMa - język C/C++ również pozwala na taki zabieg.

Zmienne w strukturze (prostej, bez dziedziczenia) ułożone są według kolejności ich deklaracji. Pierwsza zmienna struktury ma adres samej struktury, do każdej kolejnej dostaniesz adres, dodając sumę adresów wszystkich poprzednich zmiennych struktury do adresu bazowego. Tylko tutaj należy się troszeczkę zastanowić, bo jest mała pułapka.

Domyślnie kompilator wyrównuje pola struktur do ilości bajtów, niezbędnej do optymalnego czasu dostępu.

Zobacz na poniższym kodzie (takie brzydkie rzutowania dla brzydkich zastosowań rodem z C):

#include <iostream>
using namespace std;

struct S
{
    int a;
    char b;
    int c;
    bool d;
};

int main()
{
    S foo, *ptr_foo = &foo;

    foo.a = 10;
    foo.b = 'a';
    foo.c = 20;
    foo.d = false;

    cout<< *(int*)     ((int)ptr_foo) << endl; // zmienna a
    cout<< *(char*)    ((int)ptr_foo + sizeof(int)) << endl; // zmienna b
    cout<< *(int*)     ((int)ptr_foo + (sizeof(int) + sizeof(int)) ) << endl; // zmienna c
    cout<< *(bool*)    ((int)ptr_foo + (sizeof(int) + sizeof(int) + sizeof(int)) ) << endl; // zmienna d
    return 0;
}

Każda kolejna zmienna jest oddalona na moim systemie i przy użyciu GCC4.9 od poprzedniej o sizeof(int), czyli 4 bajty.

Jeśli zaś chciałbyś wymusić rozłożenie zmiennych w strukturze zgodnie z ich faktycznym rozmiarem, musisz użyć dyrektywy preprocesora pragma pack(1), która ustawia wyrównanie do 1 bajta.

#include <iostream>
using namespace std;
#pragma pack(1)

struct S
{
    int a;
    char b;
    int c;
    bool d;
};

int main()
{
    S foo, *ptr_foo = &foo;
    foo.a = 10;
    foo.b = 'a';
    foo.c = 20;
    foo.d = false;

    cout<< *(int*)     ((int)ptr_foo) << endl; // zmienna a
    cout<< *(char*)    ((int)ptr_foo + sizeof(int)) << endl; // zmienna b
    cout<< *(int*)     ((int)ptr_foo + (sizeof(int) + sizeof(char)) ) << endl; // zmienna c
    cout<< *(bool*)    ((int)ptr_foo + (sizeof(int) + sizeof(char) + sizeof(int)) ) << endl; // zmienna d
    return 0;
}

 

komentarz 31 stycznia 2016 przez MetGang Nałogowiec (34,360 p.)
Dodam od siebie, że działa to tylko ze zmiennymi w całości umieszczonymi na stacku. Jeśli spróbujesz zrobić takie coś z np. std::string - komputer może zwariować.
komentarz 1 lutego 2016 przez jegor377 Stary wyjadacz (13,230 p.)
ogólnie dzięki, całkiem spk. Nie wiedziałem o #pragma pack(1), więc na serio thx. Ogólnie to robiłem drugiego asmloadera (podobnego do tego gynvaela) i sobie pomyślałem, że moje api, które wysyłam nie może być klasą typu void, bo parametry (w sumie pisałem to w nocy xD) i napisałem przy użyciu pointerów na funkcje, które od razu statycznie typowałem i tutaj nawet dobrze, że #pragma pack(1) nie jest ustawiony, ponieważ moja struktura zachowywała się jak tablica, a tego od niej chciałem. :D
komentarz 1 lutego 2016 przez draghan VIP (106,230 p.)

Nie śledzę działań Gynvaela, więc nie mam pojęcia, o czym mówisz. ;D

Ale widzę, że nie pomogłem tutaj za bardzo, bo jednak chciałeś kod assemblera, prawda?

A o #pragma pack dowiedziałem się, kiedy pisałem dla Ciebie odpowiedź, wcześniej o tym nie słyszałem. :)

komentarz 1 lutego 2016 przez jegor377 Stary wyjadacz (13,230 p.)
pomogłeś, bo mi chodziło w jaki sposób ułożone są dane w kontenerze, a ty powiedziałeś, że ułożone są w pamięci po kolei, gdzie pierwszy jest adresem na strukturę i wszystkie są wyrównane do inta (albo słowa procesora, ale nie jestem pewien. Pewnie pisałeś to na 32bit architekturę). Dokładnie o to mi chodziło :D Teraz wiem, że struktury to takie tablice bez pragma pack(1) :D
komentarz 1 lutego 2016 przez jegor377 Stary wyjadacz (13,230 p.)
asmloader to taki mini programik, który wczytuje jakieś bajty (no w sensie czystą binarkę [jeszcze nie exe]) i wkłada go w swoją pamięć wirtualną programu i wykonuje bezpośrednio na procku. :D
komentarz 1 lutego 2016 przez draghan VIP (106,230 p.)

gdzie pierwszy jest adresem na strukturę i wszystkie są wyrównane do inta (albo słowa procesora, ale nie jestem pewien. Pewnie pisałeś to na 32bit architekturę).

Tak, 32-bitowa architektura. :) I owszem, chodzi tu o słowo procesora. :)

Podobne pytania

+1 głos
1 odpowiedź 274 wizyt
pytanie zadane 30 grudnia 2018 w Assembler przez niezalogowany
+1 głos
0 odpowiedzi 267 wizyt
pytanie zadane 9 marca 2021 w C i C++ przez ifuknowme555 Początkujący (410 p.)
0 głosów
1 odpowiedź 508 wizyt
pytanie zadane 22 lutego 2016 w C i C++ przez Mikruuus Początkujący (330 p.)

92,568 zapytań

141,420 odpowiedzi

319,620 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...