Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6085
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Увеличение от 0 до 100 в языке assembly
Это довольно странно, но я сегодня возился с ассемблером GNU (я хочу иметь возможность хотя бы читать синтаксис) и пытался заставить этот мой маленький надуманный пример работать. А именно я просто хочу перейти от 0 к 100, все время распечатывая цифры. Поэтому через несколько минут я придумываю вот что:
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
movl $0, %eax # The starting point/current value.
movl $100, %ebx # The ending point.
_loop:
# Display the current value.
pushl %eax
pushl $string
call _printf
addl $8, %esp
# Check against the ending value.
cmpl %eax, %ebx
je _end
# Increment the current value.
incl %eax
jmp _loop
_end:
Все, что я получаю от этого, - это 3 напечатанных снова и снова. Как я уже сказал, это просто немного надуманный пример, так что не беспокойтесь слишком сильно об этом, это не проблема жизни или смерти.
(Форматирование немного испорчено, но ничего серьезного).
Вы не можете доверять тому, что любая вызванная процедура делает с любым из регистров. Либо поместите регистры в стек и уберите их обратно после вызова printf, либо храните значения инкремента и конечной точки в памяти и считывайте/записывайте в регистры по мере необходимости.
Я надеюсь, что это сработает. Я предполагаю, что pushl имеет эквивалентный popl, и вы можете поместить дополнительную пару чисел в стек.
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
movl $0, %eax # The starting point/current value.
movl $100, %ebx # The ending point.
_loop:
# Remember your registers.
pushl %eax
pushl %ebx
# Display the current value.
pushl %eax
pushl $string
call _printf
addl $8, %esp
# reinstate registers.
popl %ebx
popl %eax
# Check against the ending value.
cmpl %eax, %ebx
je _end
# Increment the current value.
incl %eax
jmp _loop
_end:
Я не слишком хорошо знаком с _printf, но возможно ли, что он изменяет eax? Printf должен возвращать число напечатанных символов, которое в данном случае равно двум: '0' и '\n'. Я думаю, что он возвращает это в eax, и когда вы увеличиваете его, вы получаете 3, и это то, что вы продолжаете печатать. Возможно, Вам будет лучше использовать другой регистр для счетчика.
Вы можете безопасно использовать регистры, которые являются "callee-saved", не сохраняя их самостоятельно. На x86 это edi, esi и ebx; другие архитектуры имеют больше.
Они задокументированы в ABI ссылках: http://math-atlas.sourceforge.net/devel/assembly/
Хорошо написанные функции обычно помещают все регистры в стек, а затем вставляют их, когда они закончены, чтобы они оставались неизменными во время выполнения функции. Исключением будет eax, который содержит возвращаемое значение. Библиотечные функции, такие как printf, скорее всего, написаны именно так, поэтому я бы не стал делать то, что предлагает Клин:
Вам нужно будет сделать то же самое для любой другой переменной, которая у вас есть. Использование регистров для хранения локальных переменных в значительной степени зарезервировано для архитектур с достаточным количеством регистров для его поддержки (например, EPIC, amd64 и т. д.)
На самом деле, насколько я знаю, компиляторы обычно компилируют функции таким образом, чтобы справиться именно с этой проблемой.
@seanyboy, ваше решение является излишним. Все, что нужно, это заменить eax на какой-то другой регистр, например ecx.
Натан на правильном пути. Вы не можете предположить, что значения регистров будут неизменяться после вызова подпрограммы. На самом деле, лучше всего предположить, что они будут изменены, иначе подпрограмма не сможет выполнять свою работу (по крайней мере, для архитектур с низким числом регистров, таких как x86). Если вы хотите сохранить значение, вы должны сохранить его в памяти (например, поместить его в стек и отслеживать его местоположение).
Вам нужно будет сделать то же самое для любой другой переменной, которая у вас есть. Использование регистров для хранения локальных переменных в значительной степени зарезервировано для архитектур с достаточным количеством регистров для его поддержки (например, EPIC, amd64 и т. д.)
Вы можете переписать его так, чтобы использовать регистры, которые не должны изменяться, например %ebp . Просто убедитесь, что вы толкаете их в стопку в начале, а затем убираете в конце своей рутины.
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
push %ecx
push %ebp
movl $0, %ecx # The starting point/current value.
movl $100, %ebp # The ending point.
_loop:
# Display the current value.
pushl %ecx
pushl $string
call _printf
addl $8, %esp
# Check against the ending value.
cmpl %ecx, %ebp
je _end
# Increment the current value.
incl %ecx
jmp _loop
_end:
pop %ebp
pop %ecx