Шагая по стеку с помощью MASM

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

mov       ebx,esp
input:
get_ch    eax
cmp       eax,0dh
je        continue
push      eax
jmp       input

continue:
put_str    0ah

xor       edx,edx
output:

Вот я и потерялся...

put_ch    dword ptr [ebx-4][edx]
dec       edx
jmp       output

...с [ebx-4] и edx = 0 я могу вывести первый символ. После этого он, кажется, выводит пробелы или нулевые символы.

Любая помощь или ссылки на ссылки будут высоко оценены, мне трудно найти что-то, что я могу найти для MASM.


person ngong0    schedule 16.11.2012    source источник


Ответы (2)


1) Я не знаком с put_ch или get_ch, но я предполагаю, что put_ch dword ptr [ebx-4][edx] нуждается в ',' между вызовами EBX и EDX.

2) Вы меняете EDX на -1 каждую итерацию, но указатель (EBX) всегда находится на ebx-4. Поправьте меня, если я ошибаюсь, но не стоит ли менять EBX? Я не думаю, что -4 на самом деле вычитается из EBX при каждом итерационном прогоне.

3) Я думаю, что если вычесть из 0, как вы делаете в EBX, в сборке вы установите только флаг переполнения (OF) или, по крайней мере, SF (флаг знака). Проверьте свои флаги для реализации используемого вами ASM и посмотрите, какие команды устанавливают какие флаги.

person Community    schedule 23.01.2014
comment
Боюсь, вы ошибаетесь по всем трем пунктам. Во-первых, [ebx-4][edx] не нуждается в символе ',' между вызовами EBX и EDX, потому что он использует индексированную адресацию на основе, поэтому этот код может быть успешно собран. put_ch в данном случае является макросом. Во-вторых, цикл уменьшает EDX, который, на мой взгляд, пытается изменить эффективный адрес [ebx-4][edx], чтобы он указывал на элементы, помещаемые в список, от первого до последнего. В-третьих, OF устанавливается только тогда, когда результат знакового дополнения до двух не соответствует количеству битов, используемых для операции. SF будет установлен после уменьшения с 0. - person ; 25.01.2014

Мне кажется, что вы напрасно вычитаете 4 из эффективного адреса вашего выходного цикла. Возможно, вы думали, что скобки используются для умножения. Это не тот случай; этот тип адресации не поддерживается IA-32. В своем коде вы помещаете...

put_ch    dword ptr [ebx-4][edx]
dec       edx
jmp       output

В первой инструкции первой итерации цикла, поскольку эффективный адрес для макроса *put_ch* приводит к -4 относительно вершины кадра стека (EBX). Это число, представляющее адрес в стеке, будет передано макросу для успешной печати кода ASCII. Однако из-за инструкции dec edx вторая итерация завершится ошибкой, так как программа затем вызовет *put_ch* с аргументом -5. Поскольку двойное слово этого адреса, почти без сомнения, будет содержать 0, *put_ch* зарегистрирует его как символ NULL, сигнализируя о конце строки. Попробуй это:

dec       edx
put_ch    dword ptr [ebx][edx*4]
jmp       output

Здесь EDX уменьшается сначала и используется в макросе как индекс, который нужно умножить на четыре. Таким образом, первый адрес, переданный *put_ch*, будет -4. Второй переданный адрес будет -8. Третьему будет -12 и так далее...

Наконец, я настоятельно предлагаю при сравнении возвращаемого значения get_ch с 0dh (возврат каретки) использовать AL (1 байт), а не EAX (4 байта), если старшие 3 байта EAX содержат произвольные данные.

Удачи.

person Community    schedule 26.01.2014