Процедуры, команды усл. перехода

Тема в разделе "WASM.BEGINNERS", создана пользователем ActioN, 11 дек 2006.

  1. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    Здравствуйте, уважаемая аудитория. У меня есть нескольков вопросов.

    1. Вызываю процедуру, передавая параметры через стек. Вот такой код есть:
    Код (Text):
    1. myProc proc
    2.     push bp ; сохраняю значение bp в стеке. Перед выходом из процедуры извлеку обратно
    3.     mov  bp,sp  ; буду заносить переменные (передаваемые параметры) в регистры относительно регистра bp, кот. будет равен верхушке стека. По другому никак нельзя? Адресация только относительно bp?
    4.     mov  si,[bp+4]
    5.     mov  di,[bp+6]
    6.     ;......
    7.     pop  bp ; восстанавливаю bp
    8.     ret  4  ; передавал 4 байта в процедуру - очищаю стек и восстанавливаю ip
    9. endp
    10. push ax
    11. push bx
    12. call    myProc
    В коде выше все правильно?


    2. Логично ли использовать подряд две команды условного перехода? Под отладчиком после каждой прибавляется по 2 nop'a. Вот код:
    Код (Text):
    1.    
    2.    label:
    3.     mov  bl,byte ptr [si]
    4.     inc  si
    5.     cmp  bl,0       ; делаю сравнение, чтобы выставить соотв. флаги (отрицательное число или конец массива)
    6.     jz   exit       ; перехожу на выход из программы
    7.     jl   negative   ; перехожу на обработку отрицательных чисел
    8.     add  cx,bx
    9.     jmp  label
    10.    negative:
    11.     add  dx,bx
    12.     jmp  label
    13.    exit:  
    14. ;...
    3. У меня есть массив чисел типа db. Нужно в ходе программы динамически определять конец массива. Правильно объявить массив, в конце дописав ноль?:
    Код (Text):
    1. x   db 1,2,-3,-4,5,-6,7,-8,9,0
     
  2. murtix

    murtix New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    110
    Адрес:
    Russia
    1.
    это компилятор сам делает, можно писать просто ret, для этого и используют компилятор
    2. Логично
    3. А что ты будешь делать если в массив в ходе работы попадет 0. Конечный 0 используют для строк. В досе $. А массив на то и массив что ты обычно должен знать количество элементов
     
  3. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    2) встречал даже такой кусок (Catchy32)
    Код (Text):
    1.     test    dl, 11000000b       ;Check MOD bits
    2.     jz      c_Mod00
    3.     jp      c_CheckFlags        ;Or c_Mod11
    4.     js      c_Mod10
    3) Это твой массив, вот и думай можно ли туда 0 писать.
     
  4. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    murtix
    1. Но мне же нужно занести в регистры значения, которые я ложил в стек при вызове процедуры... Просто pop <регистр> будет извлекать значение ip, кот. ложилось при вызове. Правильно?
    3. Может тогда символ доллара использовать как конец строки. Загружать его через lodsb и сравнивать с 24h? Какой метод есть для определения конца массива?
     
  5. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    asd
    murtix:))))
    2й вопрос решен.

    3. Понял, ноль писать нельзя. А как можно максимально удобно сделать динамическое определение конца массива?
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    ActioN
    Хранить длину массива в отдельной переменной, я думаю.
     
  7. murtix

    murtix New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    110
    Адрес:
    Russia
    1. Компилятор сам это делает. Сам посмотри в дебуггере
    3.Твой массив не динамический, так что
     
  8. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    Mika0x65
    murtix
    1. Т.е. так написать?:

    myProc proc
    pop si
    pop di
    ;...
    ret
    endp
    После возвращения ip не восстанавливается...

    3. На крайний случай такое конечно можно сделать, но все же, если сделаю с долларом (массив хранит только цифры), то все правильно должно работать?
     
  9. P_F

    P_F New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2006
    Сообщения:
    116
    Адрес:
    Russia
    адресация почти по кому угодно...

    Код (Text):
    1. mov ax, [sp]
    2. mov bx, [sp+2]
    или

    Код (Text):
    1. mov eax, [esp]
    2. mov ebx, [esp+4]
    а это:
    Код (Text):
    1.  mov  si,[bp+4]
    2.  mov  di,[bp+6]
    странно размер si = 2

    Asm какой?

    myProc proc InParameter1, InParametr2, ....
    mov si, InParameter1
    ...
    ret
    endp

    ...код не совсем правильный но смысл этот.

    3. Да похрен чё туда положешь, удобнее когда в конце лежит чё то, что не может быть с массиве и всё... а вообще лучше где нибудь длинну хранить.

    PS: постарайся поточнее ...
     
  10. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    1. Сразу не заметил
    здесь не сделает т.к. откуда ему знать сколько процедура параметров принимает.
     
  11. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    ActioN
    Не обратил внимания, что массив статический. Тогда можно просто положить его длину в константу и спокойно использовать.
     
  12. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    P_F
    Юзаю tasm в режиме эмуляции masm. Может поэтому я не могу написать mov ax,[sp+4], т.к. компилер ругается, что "Illegal indexing mode"?

    По заданию мне именно надо сделать, чтобы параметры через стек передавалась без использования макросов. Так что myProc proc InParameter1, InParametr2, .... не подходит.

    Mika0x65
    Тоже, задали, чтобы концы строк и массивов определялись автоматически. Массив статистический. Насчет них точно не уверен... но все же сделаю на всякий случай... через доллар. Так делают?
     
  13. murtix

    murtix New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    110
    Адрес:
    Russia
    ActioN
    Нет, доллар это то же число представленное в виде символа
    Как выход на первое время создай массив махимальной длиной, а в отдельной переменной длину. Для мелких задач пойдет.
    x db 256 dup (?) длина 256
     
  14. P_F

    P_F New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2006
    Сообщения:
    116
    Адрес:
    Russia
    имхо изврат

    может я придераюсь но:
    Код (Text):
    1.  mov  si,[bp+4]
    2.  mov  di,[bp+6]
    всё правильно синтаксически, но:
    bp
    |0...1...|2...3|...4...5|...6|...7...8|

    после выполнения
    в si будет |0...1...|
    в di будет |...7...8|
    вопрос: так дожно быть по замыслу?

    если адресация 16 битная то по si или bp

    proc макрос.

    а как задаются массивы и строки (и вообще что под оными имеется ввиду)?

    PS: посоветовал бы юзать fasm или masm и 32 битную адресацию...
     
  15. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    murtix
    P_F
    С 3м вопросом понятно. Строки у меня объявляются так:
    enc_str db 4096 dup(?),0
    Массив:
    x db 1,2,-3,-4,5,-6,7,-8,9
    mas_len = $-x

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

    Всегда считал, что proc - функция, т.е. может вызываться из разных мест и прописывается только 1 раз в коде, а макрос - macro прописывается один раз, но при компиляции каждый раз вставляется в место вызова. Ошибаюсь?

    Мы в политехе такое проходим. А вобще, юзал masm32 раньше. Под дос всегда советовали tasm.
     
  16. murtix

    murtix New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    110
    Адрес:
    Russia
    ActioN
    macro это один из макросов
    макрос это команда для компилятора, и это не только macro, есть другие .if ... .elseif ... .endif
    В данном случае? например:
    Код (Text):
    1. FuncName proc uses edx p1 : DWORD, p2 : DWORD
    2. ...............
    3. ret
    4. FuncName endp
    будет выглядеть примерно так
    Код (Text):
    1. push ebp
    2. mov  ebp, esp
    3. push eax
    4. ..................
    5. pop  eax
    6. leave
    7. ret 8
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ActioN
    Тогда просто используй myProc как метку без всяких макросов proc и endp (кстати и ret внутри proc это тоже макрос, а не инструкция retn)
     
  18. murtix

    murtix New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    110
    Адрес:
    Russia
    Ну типа этого
    Код (Text):
    1. ............
    2. MyProc:
    3.    .......
    4.    ret     ; это надо уточнить
    5. ............
    6. ............
    7. call MyProc
    8. ............
     
  19. ActioN

    ActioN New Member

    Публикаций:
    0
    Регистрация:
    1 апр 2005
    Сообщения:
    160
    Адрес:
    Ukraine
    Спасибо всем, кто помагал. Разобрался.