Здравствуйте, уважаемая аудитория. У меня есть нескольков вопросов. 1. Вызываю процедуру, передавая параметры через стек. Вот такой код есть: Код (Text): myProc proc push bp ; сохраняю значение bp в стеке. Перед выходом из процедуры извлеку обратно mov bp,sp ; буду заносить переменные (передаваемые параметры) в регистры относительно регистра bp, кот. будет равен верхушке стека. По другому никак нельзя? Адресация только относительно bp? mov si,[bp+4] mov di,[bp+6] ;...... pop bp ; восстанавливаю bp ret 4 ; передавал 4 байта в процедуру - очищаю стек и восстанавливаю ip endp push ax push bx call myProc В коде выше все правильно? 2. Логично ли использовать подряд две команды условного перехода? Под отладчиком после каждой прибавляется по 2 nop'a. Вот код: Код (Text): label: mov bl,byte ptr [si] inc si cmp bl,0 ; делаю сравнение, чтобы выставить соотв. флаги (отрицательное число или конец массива) jz exit ; перехожу на выход из программы jl negative ; перехожу на обработку отрицательных чисел add cx,bx jmp label negative: add dx,bx jmp label exit: ;... 3. У меня есть массив чисел типа db. Нужно в ходе программы динамически определять конец массива. Правильно объявить массив, в конце дописав ноль?: Код (Text): x db 1,2,-3,-4,5,-6,7,-8,9,0
1. это компилятор сам делает, можно писать просто ret, для этого и используют компилятор 2. Логично 3. А что ты будешь делать если в массив в ходе работы попадет 0. Конечный 0 используют для строк. В досе $. А массив на то и массив что ты обычно должен знать количество элементов
2) встречал даже такой кусок (Catchy32) Код (Text): test dl, 11000000b ;Check MOD bits jz c_Mod00 jp c_CheckFlags ;Or c_Mod11 js c_Mod10 3) Это твой массив, вот и думай можно ли туда 0 писать.
murtix 1. Но мне же нужно занести в регистры значения, которые я ложил в стек при вызове процедуры... Просто pop <регистр> будет извлекать значение ip, кот. ложилось при вызове. Правильно? 3. Может тогда символ доллара использовать как конец строки. Загружать его через lodsb и сравнивать с 24h? Какой метод есть для определения конца массива?
asd murtix))) 2й вопрос решен. 3. Понял, ноль писать нельзя. А как можно максимально удобно сделать динамическое определение конца массива?
Mika0x65 murtix 1. Т.е. так написать?: myProc proc pop si pop di ;... ret endp После возвращения ip не восстанавливается... 3. На крайний случай такое конечно можно сделать, но все же, если сделаю с долларом (массив хранит только цифры), то все правильно должно работать?
адресация почти по кому угодно... Код (Text): mov ax, [sp] mov bx, [sp+2] или Код (Text): mov eax, [esp] mov ebx, [esp+4] а это: Код (Text): mov si,[bp+4] mov di,[bp+6] странно размер si = 2 Asm какой? myProc proc InParameter1, InParametr2, .... mov si, InParameter1 ... ret endp ...код не совсем правильный но смысл этот. 3. Да похрен чё туда положешь, удобнее когда в конце лежит чё то, что не может быть с массиве и всё... а вообще лучше где нибудь длинну хранить. PS: постарайся поточнее ...
ActioN Не обратил внимания, что массив статический. Тогда можно просто положить его длину в константу и спокойно использовать.
P_F Юзаю tasm в режиме эмуляции masm. Может поэтому я не могу написать mov ax,[sp+4], т.к. компилер ругается, что "Illegal indexing mode"? По заданию мне именно надо сделать, чтобы параметры через стек передавалась без использования макросов. Так что myProc proc InParameter1, InParametr2, .... не подходит. Mika0x65 Тоже, задали, чтобы концы строк и массивов определялись автоматически. Массив статистический. Насчет них точно не уверен... но все же сделаю на всякий случай... через доллар. Так делают?
ActioN Нет, доллар это то же число представленное в виде символа Как выход на первое время создай массив махимальной длиной, а в отдельной переменной длину. Для мелких задач пойдет. x db 256 dup (?) длина 256
имхо изврат может я придераюсь но: Код (Text): mov si,[bp+4] 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 битную адресацию...
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.
ActioN macro это один из макросов макрос это команда для компилятора, и это не только macro, есть другие .if ... .elseif ... .endif В данном случае? например: Код (Text): FuncName proc uses edx p1 : DWORD, p2 : DWORD ............... ret FuncName endp будет выглядеть примерно так Код (Text): push ebp mov ebp, esp push eax .................. pop eax leave ret 8
ActioN Тогда просто используй myProc как метку без всяких макросов proc и endp (кстати и ret внутри proc это тоже макрос, а не инструкция retn)
Ну типа этого Код (Text): ............ MyProc: ....... ret ; это надо уточнить ............ ............ call MyProc ............