Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];

Вниз

Объединение строк в ASM   Найти похожие ветки 

 
Gydvin ©   (2006-02-25 20:26) [0]

Здравствуйте мастера, тут короче ассемблер начал ковырять, ну и возникла небольшая проблемка.

короче
в двух регистрах находся по слову, например
eax  =  "Hello"
edx = "world"
как бы мне в eax или еще где, получить "Hello world".

чур только больно небить.

Зы. Может есть линки, на литературу по ASM для начинающих, где б доступным языком были б описаны основы.


 
Defunct ©   (2006-02-25 20:50) [1]

ну во превых, в регистрах слов быть не может, в регистрах указатель на строку...

Чтобы строки можно воспользоваться строковыми командами: movs, lods, stos. Только необходимо выделить память под третью строку, куда будет помещен результат объединения строк.

> Зы. Может есть линки, на литературу по ASM для начинающих,
Лучше купить книгу..


 
Gydvin ©   (2006-02-25 21:04) [2]

Defunct ©   (25.02.06 20:50) [1]
Лучше купить книгу..

Может какую конкретно посоветуете

movs, lods, stos
Ага понятно.

А вобще стоит такая задача:
Вот аналог в делфях

r:array of integer;
for x:=0 to 100 do begin

  if r[x]=0 then s:=s+"0" else s:=s+"1";
end;

где "1" и "0" хранится по некому адресу

я уже со всем разобрался вот только проблемы с s:=s+


 
Defunct ©   (2006-02-25 21:11) [3]

> Может какую конкретно посоветуете
Новых книг для начинающих - не знаю, из старых - "Ассемблер для IBM PC и программирования", П. Абель.

> я уже со всем разобрался вот только проблемы с s:=s+
ну например так:

 mov  al, <символ который надо добавить к строке>
 mov  edi, <адрес строки + текущая длина строки >
 stosb  // <добавление символа в конец строки и автоинкремент edi >
 
только память под строку должна быть выделена с запасом!


 
Gydvin ©   (2006-02-27 11:50) [4]

что-то немогу вьехать что я тут неправильно сделал

PUSH EBP
MOV EBP,ESP
SUB ESP,50 ; резервирую место в стеке
MOV AL,61    ; Символ "a"
MOV EDI,DWORD PTR DS:[ebp-50]
STOS BYTE PTR ES:[EDI] ; уже здесь  "Ошибка записи по адресу 00000000"
STOS BYTE PTR ES:[EDI]
STOS BYTE PTR ES:[EDI]
MOV EAX,DWORD PTR DS:[ebp-50]
LEAVE
RETN


 
Defunct ©   (2006-02-27 11:58) [5]

Ну дык понятно, а что ж вы хотели?

push  ebp
mov   ebp, esp   ; <-- ebp указывает на вершину стека (начало строки)
sub    esp, 50
mov   al, "a"
mov   edi, ebp ; адрес начала строки
stosb
stosb
stosb
mov  eax, [ebp]   ; не надо адресовать ds через ebp, оставьте ss для ebp
add  esp, 50       ; восстановить указатель стека!!
ret


 
Defunct ©   (2006-02-27 12:02) [6]

zzz теперь уже я гоню, насмотревшись на ваш код.. извиняюсь.

sub   esp, 50    
mov   edi, esp   ; адрес начала строки
mov   al, "a"
stosb
stosb
stosb
mov   eax, [esp]  
add  esp, 50       ; восстановить указатель стека
ret


 
Сергей М. ©   (2006-02-27 12:29) [7]


> Gydvin


А в чем прелесть реализации всего этого на asm"е ?
Ты сомневаешься в эффективности соответствующего кода, генерируемого компилятором для того же алгоритма, но на Паскале ?


 
Defunct ©   (2006-02-27 12:34) [8]

Сергей М. ©   (27.02.06 12:29) [7]

Человек изучает асм, что в этом плохого? Причем тут сомнения относительно кода генерируемого компилятором с паскаля?


 
Gydvin ©   (2006-02-27 12:36) [9]

делаю так

PUSH EBP
MOV EBP,ESP
SUB ESP,50
MOV AL,61
MOV EDI,EBP
STOS BYTE PTR ES:[EDI]
MOV AL,62
STOS BYTE PTR ES:[EDI]
MOV AL,63
STOS BYTE PTR ES:[EDI]
MOV EAX,DWORD PTR SS:[EBP]
add ESP,50
POP EBP
RETN ; теперь при выходе таже ошибка


 
Gydvin ©   (2006-02-27 12:38) [10]

Gydvin ©   (27.02.06 12:36) [9]

ой не видел остальные посты


 
Gydvin ©   (2006-02-27 12:42) [11]

Сергей М. ©   (27.02.06 12:29) [7]

Ну воперевых [8], а во вторых дописываю функционал, для одной очень для меня интересной, но старой проги, а аналогов я для нее пока не нашел :(


 
Сергей М. ©   (2006-02-27 12:46) [12]


> Defunct ©   (27.02.06 12:34) [8]


Да я собственно не против ... просто поинтересовался ..


 
Gydvin ©   (2006-02-27 12:50) [13]

Defunct ©   (27.02.06 12:02) [6]

Большое спасибо, все работает


 
Сергей М. ©   (2006-02-27 12:51) [14]


> теперь при выходе таже ошибка


Ну ты стек-то сбалансировал перед RET !
Поэтому и ошибка ..

Кр.того, все та же ошибка : вместо
mov edi, esp
ты опять пишешь
mov edi, ebp


 
Сергей М. ©   (2006-02-27 12:54) [15]


> все работает


Возвращать результат по ссылке на область стека, нач.адрес которой < esp, нельзя - результат будет непредсказуем.


 
Defunct ©   (2006-02-27 13:03) [16]

там не ссылка возвращается, а непосредственные данные через eax..

а причина глюка с выходом была в том, что по [ebp] находится адрес возврата, и он затирался командами stosb, т.к. edi = ebp...

если надо возвращать строку, то память нужно выделять перед вызовом функции, тогда действительно надо будет делать манипуляцию с ebp (и работать с данными [ebp + смещение]


 
Gydvin ©   (2006-02-27 13:03) [17]

Сергей М. ©   (27.02.06 12:54) [15]

Хм, а как надо, можно напримере если не тяжело


 
Defunct ©   (2006-02-27 13:17) [18]

> можно напримере если не тяжело

напр. так:

 sub  esp, 50
 call  GetString  
; после этого вызова в стеке по адресы [esp] будет лежать строка
; где первый байт - длина - далее символы латинского алфавита..
 ...

; ---> зарезервированное место под рез-тат в стеке
; <--- строка в выделенной области памяти (первый байт - длина)
GetString:
  push ebp
  mov  ebp, esp

  mov  ecx, "z"-"a"+1 ; будем выводить лат. алфавит
  mov  [ebp+8], cl      ; длину будущей строки знаем и сразу заносим в первый байт строки
  mov  al, "z"          ; строку заполняем с конца
_do_fill_str:
  mov  [ebp + ecx + 9], al  ; сохраняем тек. символ
  dec   eax           ; код будет эффективнее чем dec al
  loop  _do_fill_str      

  pop   ebp
  ret


 
Сергей М. ©   (2006-02-27 13:30) [19]


> Defunct ©   (27.02.06 13:03) [16]
> там не ссылка возвращается, а непосредственные данные через
> eax


Ага, вижу уже ..


> Gydvin ©   (27.02.06 13:03) [17]
> а как надо, можно напримере если не тяжело


Сначала ты должен определиться с типом результата.

Пример:

function ConcatenateTwoStrings(const Str1, Str2: String): String;
//эквивалентно Паскаль-строке Result := Str1 + Str2;
asm
 push  eax
 push  edx
 mov eax, Result
 pop   ecx
 pop  edx
 call System.@LStrCat3
end;


 
Gydvin ©   (2006-02-27 13:34) [20]

Если я правильно понял [6], то там в eax находится результат работы и чтоб я его мог использовать из другой процедуры я должен положить их на какой либо глобальный адрес, предварительно его создав


 
Gydvin ©   (2006-02-27 13:38) [21]

mov eax, Result

В том то и дело что я пишу в памяти который сохраняю (если меня устраивает результат) в ехе и потому там такие переменые как result, bufer и т.п неканают, а то б было гораздо проще, а еще с жесткой адресацией бр.


 
Сергей М. ©   (2006-02-27 13:52) [22]


> который сохраняю ... в ехе


А я где по-твоему сохраняю ?


> переменые как result, bufer и т.п неканают


Result в дан.контексте - это не переменная, это зарезервированное слово, под которым компилятором подразумевается адрес области памяти, имеющей структуру AnsyString, которую компилятор динамически распределил перед вызовом ф-ции для возврата результата конкатенации.

И что вообще значит "неканают" ?


>  жесткой адресацией бр


Что подразумевается под этим ?


 
Gydvin ©   (2006-02-27 13:59) [23]

Сергей М. ©   (27.02.06 13:52) [22]

короче ехе открываешь отладчиком со встроеным дизасемблером и там дорисовываешь все что тебе нужно, так же там имеется возможность сохранить результат работы непосредственно в исполняемый файл.


 
Сергей М. ©   (2006-02-27 14:11) [24]


> Gydvin ©   (27.02.06 13:59) [23]


Т.е. речи о Делфи вообще не идет ?

Ну тогда ты должен определиться, где и как распределяется память под результат и кто (вызываемая или вызывающая подпрограмма) ответственен за ее аллокацию/реаллокацию/освобождение, если речь идет о динамической памяти.


 
Gydvin ©   (2006-02-27 14:21) [25]

ответственен за ее аллокацию/реаллокацию/освобождение

Мдяя тяжелый случай, ну да ладно как нибуть разберусь


 
Сергей М. ©   (2006-02-27 14:27) [26]


> Gydvin ©   (27.02.06 14:21) [25]


Творческих тебе узбеков !)



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.03.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.013 c
15-1140039582
Petr V. Abramov
2006-02-16 00:39
2006.03.12
UPS APC от 1КВт 19U стойкомонтируемые


15-1140406651
никак не получается
2006-02-20 06:37
2006.03.12
таблицы


2-1140418343
unit
2006-02-20 09:52
2006.03.12
Базы данных


3-1137239764
KUNAK
2006-01-14 14:56
2006.03.12
FireBird and Win98


2-1140437038
Василь Быков
2006-02-20 15:03
2006.03.12
Как добавить поле в таблицу ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский