vector a asm

0

Witam. Jak sie odnosic do elementow kontenera vector w asm? Kod ponizej niestety nie przypisuje zadanej wartosci. Z tego co widze, to obiekt ma procz samej tablicy jeszcze dwa pola size i capacity, w zwiazku z tym probowalem przesunac "wskaznik" o 8 bajtow do przodu, niestety rozsypuje to caly kontener.

 
           int n
	cout << "Podaj zakres liczb: ";
	cin >> n;

	vector <int> tab(n);


	__asm  //wypelnianie
	{
		lea esi,tab
		mov eax,0
	wypelnianie:
		inc eax
		mov [esi+4*eax-4],eax


		cmp eax,n
	jnz wypelnianie
	}

Any idea?

0

Zrób sobie zmienną pomocniczą int *start = &tab.front(); i z niej bierz adres we wstawce. W ostateczności możesz poczytać źródła używanej przez Ciebie implementacji wektora i ręcznie grzebać w polach, ale to całą kupę wad.

0

W samym c++ ta referencja dziala. Zrobilem w ten sposob, nie dziala:

	vector <int> tab(n);
	int *glowa = &tab.front();

	__asm
	{
		lea esi,glowa+4 // +4 bo wskaznik zajmuje 4 bajty
		mov eax,0
	wypelnianie:
		inc eax
		mov [esi+4*eax-4],eax


		cmp eax,8
	jnz wypelnianie
	}

W debugerze podczas wykonywania petli nie przypisuje elementom tablicy zadnych wartosci, natomiast przy ostatniej iteracji zdaje sie, ze wchodzi juz na adres pola size/capacity...

O ile dobrze rozumiem to dziala na tej samej zasadzie jak bym dal lea esi,tab[0]?

0

Tylko gdyby tab był int *. Weź zrozum, że vector to nie jest zwykła tablica, technicznie jest to struktura nafaszerowana polami (a właściwie najczęściej chyba wskaźnikiem na obiekt implementacji, żeby umożliwić kilka tricków), bez znajomości fimplementacji nie masz prawa w tym grzebać bezpośrednio. Zmień warunek pętli (skok, kiedy indeks jest poniżej rozmiaru, jb) i używaj sensownej składni, zawsze ujmuj dostęp do pamięci w [], te MASMowe zaszłości są strasznie nieczytelne w większym kodzie. Tak w ogóle to dlaczego wczytujesz rozmiar tablicy jako liczbę ze znakiem?

0

Cholera, jakimś cudem urwało mi kod, nieważne, pierwsza linia to ma być mov esi, [glowa], masz wczytać wartość zmiennej do rejestru, ustawić sobie adres w esi na ten wyliczony przez kod w C++. Obecnie to radośnie psujesz stos, lea bierze obliczony adres z operandu, nie znajdującą się pod nim wartość.

0

Jak sie odnosic do elementow kontenera vector w asm?
Nie odnosić się. Wewnętrzna budowa takiej klasy może się zmieniać z wersji na wersję, np. Visual C++ 2008, 2010 i 2012 mają różne implementacje wielu klas STL-a.

0

Najlepiej wywołać po prostu push_back. Jeżeli zależy ci na wydajności to zrezygnuj z wektora i przygotuj wcześniej odpowiednio duży bufor.

Wywołać push_back z poziomu wstawki masma w Visual Studio możesz tak:

std::vector<int> vector;

typedef void (__thiscall std::vector<int>::*_push_back)(const int&);
_push_back push_back = &std::vector<int>::push_back;

__asm
{
	push 0x69
	push esp

	lea ecx, vector
	call push_back

	add esp, 4
}

push_back chce referencję, a nie wartość, więc trzeba mu podać adres. Także robimy sobie zmienną lokalną (de facto wrzucamy ją na stos) i wrzucamy ją na stos jako argument. push_back zrzuci go sobie, ale trzeba potem jeszcze posprzątać po naszej zmiennej tymczasowej.

0
Rev napisał(a):

Najlepiej wywołać po prostu push_back. Jeżeli zależy ci na wydajności to zrezygnuj z wektora i przygotuj wcześniej odpowiednio duży bufor.

Pewnie nie może, jakiś rozwolniony psychicznie profesor wymaga inline asm w C++ na zaliczenie, mile widziane użycie STL. W paru innych miejscach ostatnio pojawiły się wątki o operacjach na tablicach/wektorach via wstawki. Idę o zakład, że to kolejny przypadek.

0

@PS trafiles w dziesiatke :) Przy okazji omawiania tablic na ASK, stwierdzil, ze mamy napisac algorytm sita erastotenesa w asm, bazujac na wektorach (ktorych swoja droga nawet nie omawialismy na obiektowym). Ciekaw jestem, czy sam kiedykolwiek probowal operowac na vector w asm, jutro chyba go poprosze, zeby sam nam to zaimplementowal :) Tymczasem ja jednak rezygnuje i napisze to na statycznej tablicy, ale bardzo wszystkim dziekuje za probe pomocy.

0

No i przecież używa inline assembly oraz STL, jaki problem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1