2012-06-05 11 views
5

Obecnie pracuję nad zadaniem w co & T Zgromadzenia i teraz muszę dołączyć dwa ciągi:Dołączanie dwa ciąg w zespole x86

message: .asciz "String 1" 
before: .asciz "String 2" 

ja naprawdę nie wiem, jak to zrobić lub jak zaczynać. Już szukałem w Internecie, ale nie mogłem znaleźć żadnych przydatnych informacji. Myślę, że muszę ręcznie skopiować znaki drugiego ciągu na końcu pierwszego ciągu, ale nie jestem tego pewien.

Czy ktoś mógłby mi wyjaśnić, jak to zrobić? :)

+0

Montaż AT & T nie istnieje, jest to po prostu inna składnia. Chyba chodziło ci o x86? :) – BlackBear

+0

To właśnie miałem na myśli;) – Devos50

+0

Ok, skorzystałem z możliwości edycji Twojego zadania :) – BlackBear

Odpowiedz

2

To nie jest sprawa trywialna. Łańcuchy mają różną długość i zajmują różne spacje w pamięci i musi istnieć jakiś sposób, aby wiedzieć, jak długo są lub gdzie się kończą. W C lub C++, nul bajty (bajty o wartości zerowej) wskazuje koniec łańcucha. Z niektórymi innymi językami programu , masz wskaźnik do początku łańcucha i długości ciągu przechowywanych osobno, co ma tę zaletę, że pozwala ci przechowywać w łańcuchu dane binarne (w tym bajty o wartości zerowej ). Nawet z C i resztą, musisz mieć wskaźnik do miejsca, w którym zaczyna się ciąg.

Co zwykle musi się zdarzyć, to że musisz użyć asm, aby skontaktować się z systemem operacyjnym i poprosić o blok wolnej pamięci, który jest wystarczająco duży, aby pomieścić zawartość dwóch łańcuchów po ich dołączeniu.To byłaby pamięć oddzielona od jednego z dwóch ciągów, od których zaczyna się, i pochodzi z tego, co nazywa się Stosem Pamięci. Gdy otrzymasz punkt początkowy tego bloku pamięci, skopiujesz zawartość pierwszego ciągu znaków do niego, następnie kontynuuj, kopiując zawartość drugiego ciągu znaków pod numerem tuż za pierwszym. Następnie zwolnij pamięć, która została przypisana do pierwszego ciągu znaków i przypisz blok do tego ciągu, zmieniając jego wskaźnik, a być może na jego długość: . Zwolniona pamięć jest zwracana do sterty pamięci przez system operacyjny do ponownego użycia w innym miejscu.

W rzeczywistości system operacyjny nie jest jedynym źródłem zwalnianej pamięci. Niektóre kompilatory, nawet asemblery, samodzielnie zarządzają pamięcią lub dostarczają programistom odpowiednie narzędzia, aby zrobić to w razie potrzeby.

Innymi słowy, może to być bardzo ambitne przedsięwzięcie i trzeba trochę wiedzieć o tym, co się dzieje, aby zrobić to dobrze. Robisz to źle, możesz spodziewać się konsekwencji takich jak awarie systemu i konieczność ponownego uruchomienia komputera.

+0

Nie jestem pewien, w jaki sposób możesz zawiesić system, uruchamiając program łączący łańcuchy. – Simon

5

To pytanie nie wspomina o docelowej pamięci, co sprawia, że ​​trudno jest odpowiedzieć. Nie wiem też, czy jesteś w wersji 16-bitowej, 32-bitowej czy 64-bitowej. Dla ułatwienia, po prostu założę, że są one zakończone znakiem C w stylu 0.

W każdym razie, to wydaje się być ogólna procedura:

  • Pobiera długość pierwszego ciągu (instrukcje dotyczące pisania strlen asm można znaleźć tutaj: http://www.int80h.org/strlen/)
  • Ustaw ptr do celu pamięć
  • Skopiuj pierwszy ciąg do pamięci docelowej, używając rep(e/ne) movsb o rozmiarze w ecx.

Może to być CPU zoptymalizowane za pomocą „MOVSD” najpierw robi shr ecx, 2 na swojej długości, aby dostać go w partiach po 4 bajty, a następnie robi resztę z movsb. Widziałem to zrobić tak:

mov  edi, dest 
mov  esi, string_address 
mov  ecx, string_length 
mov  eax, ecx 
shr  ecx, 2 
repne movsd 
mov  cl, al 
and  cl, 3 
repne movsb ; esi and edi move along the addresses as they copy, meaning they are already set correctly here 
  • Pobiera długość drugiego ciągu (należy wykonać kopię zapasową edi w stosie lub innego rejestru, jeżeli zajdzie taka potrzeba; zawiera on adres, który należy skopiować następny ciąg do)
  • Skopiuj drugi ciąg do pamięci docelowej (tak jak powiedziałem, poprawny adres powinien znajdować się w edi po pierwszej operacji na łańcuchu)
  • Dla bezpieczeństwa, dodaj nowe 0 za nim.

Jeśli kopiujesz drugi ciąg do końca pierwszego napisu, trzeba jeden mniej operacji kopiowania, ale masz aby upewnić się, że rzeczywiście jest tam wystarczająco dużo miejsca, aby skopiować drugi ciąg bez nadpisywania inne ważne rzeczy.