Zamiana wielkości liter-ASSEMBLER

0

Witam, mam następujący problem: mam za zadanie wykonać banalną rzecz- zamianę liter w wyrazie z dużych na małe. Żeby uprościć początkową fazę, próbuję zmienić wielkość litery 'H' z dużej na małą. Wiem, że można to wykonać operacją XOR na danej literze i stałej 0x20. Niestety nie wiem, dlaczego w programie to nie działa... P.S. próbowałem przenieść wybraną literę do al i ten rejestr xor-ować, ale potem wyskakiwał mi błąd konsolidacji: "relocation truncated to fit R_386_16 against .data", więc zaniechałem tego i postanowiłem operować na eax. Co ciekawe, litera wyświetla się na ekranie (oczywiście jako duże 'H'), gdy zamiast XOR użyłem OR. Natomiast przy operacji XOR nic się nie wyświetla. Po debuggowaniu programem gdb widziałem, że w rejestrze eax istotnie zmieniła się wartość przechowywana, więc operacja XOR wydaje mi się działać poprawnie. Nie wiem tylko, dlaczego przeniesienie z eax do ecx kończy się fiaskiem (chyba, że błąd jest gdzie indziej). Czy ktoś może pomóc? :)

section .data
text db "HellO", 0xa

section .text
global _start
_start:
mov edx, 1       ; dlugosc tekstu- tu: 1, bo przenosze tylko jeden znak 
mov eax, text  ; wskaznik na tekst przenoszony do rejestru eax
xor eax, 0x20  ; zamiana wielkosci litery z akumulatora na mala 
mov ecx, eax  ; przeniesienie tej litery do rejestru ecx celem wyswietlenia
mov ebx, 1      ; 1 == STDOUT
mov eax, 4      ; 4 == sys_write
int 0x80           ; call kernel

; EXIT_CODE
mov eax, 1
mov ebx, 0
int 0x80

1

No dobra, ale rozumiesz czemu ten xor miałby zamienić liczbę na małą? Bo mam wrażenie że nie. Stąd też nie rozumiesz co się dzieje z wartościami i dlatego ten kod nie działa.
Krótkie wyjaśnienie:
H to znak numer 72 (czyli 0x48) a h to znak 104 (czyli 0x68). 0x20 to jest 32. Jak nie trudno zauważyć 104-72 = 32. Więc w praktyce mógłbyś zamiast tego xora dać tam po prostu add. Byłoby to zresztą nieporównywalnie bardziej czytelne dla zwykłego śmiertelnika.
A teraz czemu to co podałeś nie działa?

  1. mov eax, text to jak mniemam robi mov eax, offset text czyli ustawia wartość eax na ADRES tablicy text. Podkreślam, chodzi tu o ADRES a nie wartość.
  2. xor eax, 0x20 to modyfikuje ADRES przechowywany w rejestrze eax a nie WARTOŚĆ (czyli na przykład literkę H). Więc nagle zamiast pokazywać na ten swój string, pokazujesz na jakieś losowe miejsce w pamięci. Próba wypisania znaku pod tym adresem niewątpliwie nie przyniesie zamierzonego skutku...

Ty chcesz zmieniać WARTOŚCI w tej tablicy, więc musisz sobie wyłuskać wartość spod wskaźnika i ją zmodyfikować.

0

Dziękuję za wyczerpującą odpowiedź, teraz zrozumiałem swój błąd i udało się poprawić go. Oto działający kod, jakby ktoś był jeszcze zainteresowany:

section .data
text db "HellO", 0xa
len equ $-text

section .text
global _start
_start:
mov edx, 1
mov eax, text
add byte [eax], 0x20  ; litera mala rozni sie od duzej o 32 (w kodzie ascii)
mov ecx, eax
mov ebx, 1
mov eax, 4
int 0x80

mov eax, 1
mov ebx, 0
int 0x80

Pozdrawiam ;)

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