Регистр и переменная

Тема в разделе "WASM.BEGINNERS", создана пользователем Lex2029, 2 ноя 2007.

  1. Lex2029

    Lex2029 New Member

    Публикаций:
    0
    Регистрация:
    17 сен 2007
    Сообщения:
    199
    Всем привет.
    Я просто не понимаю в чем дело? Подскажите плиз!
    Есть код, считает длину строки, ну до того пока 0 не появится.

    Код (Text):
    1. GetLen PROC lpStr:LPSTR
    2.     xor         eax,eax
    3.     mov         edx,lpStr
    4.     .while TRUE
    5.         mov     bl,BYTE PTR[xxxxxxx]
    6.         .break .if bl==0
    7.         inc eax
    8.         inc edx
    9.         inc lpStr
    10.     .endw
    11.     ret
    12. GetLen ENDP
    Если вместо xxxxxxx поставить edx, то все работает, а если поставить lpStr, то ничего не работает!!! Как так может быть?
     
  2. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Lex2029
    Потому что инструкция
    mov bl,BYTE PTR [lpStr] Вытащит один байт из дворда lpStr
     
  3. Lex2029

    Lex2029 New Member

    Публикаций:
    0
    Регистрация:
    17 сен 2007
    Сообщения:
    199
    А я думал она перейдет на адрес указанный в lpStr и возьмет 1 байт...
    А почему не так, когда с edx?
     
  4. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Потому что [РЕГИСТР] обозначает обращения к памяти по адресу, записанному в регистре, а [ПЕРЕМЕННАЯ] - к переменной, т.к. ассемблер вместо имени подставит адрес. Эквивалентно [offset ПЕРЕМЕННАЯ]. Вообще синтаксис MASM не требует обязательной постановки скобок при обращении к переменной, иногда вводя путаницу.
     
  5. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Vov4ick
    Lex2029

    Говоря проще, ПЕРЕМЕННАЯ и [ПЕРЕМЕННАЯ] -- это одно и то же, а вот РЕГИСТР и [РЕГИСТР] -- разные вещи.

    В случае с переменной в обоих случаях произойдёт обращение к области памяти, занимаемой этой переменной (в приведённом выше примере -- к указателю на строку), а вот с регистрами явная разница: без скобок обращение происходит к содержимому самого регистра, а со скобками -- к ячейке памяти, адрес которой содержит в этом регистре.
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    SII
    Только в масме. В "правильном" ассемблере var будет означать адрес переменной, а [var] - значение по этому адресу. Собственно, в reg также может лежать адрес чего-либо, тогда [reg] - значение по этому адресу, что эквивалентно операциям с переменными.
     
  7. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    IceStudent
    Ну это вопрос спорный какой ассебмблер правильный =)
     
  8. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Mental_Mirror
    Хоть я и учусь сейчас на масме, давно уже понял, что фасм нааамного круче.
     
  9. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    IceStudent

    Знаем, знаем про особенности NASM. В определённой степени это действительно удобнее: наблюдается единобезобразие в записи операндов. Но человек-то, как видно из примера, говорил про MASM.
     
  10. Lex2029

    Lex2029 New Member

    Публикаций:
    0
    Регистрация:
    17 сен 2007
    Сообщения:
    199
    Спасибо!
     
  11. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Код (Text):
    1. GetLen PROC lpStr:LPSTR
    2.     xor eax,eax
    3.     mov edx,offset lpStr; вариант lea edx,lpStr
    4.     .while TRUE
    5.         mov     bl,BYTE PTR[edx+eax]
    6.         .break .if bl==0
    7.         inc eax    
    8.     .endw
    9.     ret
    10. GetLen ENDP
    или так
    Код (Text):
    1. GetLen PROC lpStr:LPSTR
    2.     xor eax,eax
    3.     .while TRUE
    4.         mov     bl,BYTE PTR[eax+lpStr]
    5.         .break .if bl==0
    6.         inc eax
    7.     .endw
    8.     ret
    9. GetLen ENDP
    а ещё вот так
    Код (Text):
    1.     mov esi,offest lpStr
    2. s_check: lodsb                  
    3.      test al, al            
    4.      jne s_check
    5.      sub esi,offset lpStr+1
    и так
    Код (Text):
    1.     mov edi, offest lpStr
    2.     xor al, al              
    3. s_check: scasb          
    4.     jne s_check
    5.     sub edi,offest lpStr+1
    или совсем незатейливо
    Код (Text):
    1.     mov edi, offest lpStr
    2.     xor al, al
    3.     or ecx,-1            
    4.     repne scasb          
    5.     not ecx
     
  12. Lex2029

    Lex2029 New Member

    Публикаций:
    0
    Регистрация:
    17 сен 2007
    Сообщения:
    199
    круто :)) Спасиб!