| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #60 : 04-10-2009 15:46 »  |  | 
 
 цитирую Брэдли:Компьютер снабжает стек зарезервированным участком памяти и указателем, называемым указателем стека. Программа использует указатель стека для того, чтобы фиксировать последние помещенные в стек данные, в отличие от почты, где сами элементы очереди продвигаются вперед по мере движения очереди. В компьютере намного легче использовать для слежения за данными указатель и при записи или считывании данных из стека изменять только его. В ответ на выполнение операций POP и PUSH указатель стека соответственно увеличивается или уменьшается.
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #61 : 04-10-2009 15:49 »  |  | 
 
 Anarky, цитировать - не велика заслуга. Попробуй своим умом думать. Вопрос я задал очень простой и если ты хоть немного знаешь материал, то ответ найдешь, а за тем и ошибку в твоем последнем листинге. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #62 : 04-10-2009 16:02 »  |  | 
 
 pop bpmov ax,bp
 ax: будет элемент, который мне нужен?
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #63 : 04-10-2009 16:15 »  |  | 
 
 Anarky, это игра-угадайка ни к чему не ведет.Вот тебе вопрос попроще: перечисли все команды, работающие со стеком.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #64 : 04-10-2009 17:04 »  |  | 
 
 call вызывает подпрограмму, сохраняя адрес возврата ret выход из подпрограммы по сохраненному адресу возврата model smallstack 256
 .data
 sm   dw 16
 otv  dw  ?
 .code
 next:
 push -3
 push -2
 push -1
 push 0
 push 1
 push 2
 push 3
 push 4
 call sum
 sum:
 pop ax
 cmp ax,0            ; сравниваем ax с нулем
 jb go
 go:
 mov dx,otv
 add otv,ax
 ret
 jge sum                ; если больше или равен то sled
 
 ret
 end sum
 mov ax,4c00h
 int 21h
 end next
 
вот к чему я пришел, но не работает   |  
						| 
								|  |  
								| « Последнее редактирование: 06-10-2009 15:07 от Sel » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #65 : 04-10-2009 17:33 »  |  | 
 
 Anarky, Ты с начало объясни, что ты хочешь сделать.
 Ты хочешь передавать в функцию весь массив для его суммирования или всего два элемента которые будет данная функция суммировать и возвращать результат?
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #66 : 04-10-2009 17:35 »  |  | 
 
 мне нужно брать элемент из стека, если отрицательный, то складывать, если 0 и больше ничего не делать: брать следующий... |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #67 :  04-10-2009 17:40 »   |  | 
 
 мне нужно брать элемент из стека, если отрицательный, то складывать, если 0 и больше ничего не делать: брать следующий...
 Ты пойми одно. Вызываемая функция должна ничего не знает о данных которые находятся где то там у тебя в программе. Она либо должна получать указатель на массив для суммирования и его длину, после чего она суммирует все элементы и возвращает результат. Либо второй вариант, она получает два элемента, суммирует их и возвращает результат. Ты определись, чего ты хочешь. Anarky, не пытайся мудрить с этим стеком. Лично я как вижу решение твоей задачи. В основном цикле программы ты проверяешь значение из массива на отрицательное значение, если оно отрицательное то ты передаешь (через стек) данное значение и аккумулируемое значение (т.е. значение в котором накапливается результат суммирования) функции суммирования, она суммирует два значения и возвращает результат в регистре AX. И так повторяешь для всех данных в массиве. |  
						| 
								|  |  
								| « Последнее редактирование: 06-10-2009 15:09 от Sel » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #68 : 04-10-2009 17:51 »  |  | 
 
 надо взять из стека элементы, сложить отрицательные, а для этого надо указать где они хранятся в стеке... Anarky, не пытайся мудрить с этим стеком.
 Лично я как вижу решение твоей задачи. В основном цикле программы ты проверяешь значение из массива на отрицательное значение, если оно отрицательное то ты передаешь (через стек) данное значение и аккумулируемое значение (т.е. значение в котором накапливается результат суммирования) функции суммирования, она суммирует два значения и возвращает результат в регистре AX. И так повторяешь для всех данных в массиве.
 
 именно это я и пытаюсь сделать, только массив=стек Формально моя задача звучит так:Составить программу, выполняющую обработку массива, аналогично заданию предыдущей работы, но оформленной в виде "ближней" процедуры, параметры в которую передаются через стек. 
 |  
						| 
								|  |  
								| « Последнее редактирование: 04-10-2009 17:58 от RXL » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #69 : 04-10-2009 17:57 »  |  | 
 
 надо взять из стека элементы, сложить отрицательные, а для этого надо указать где они хранятся в стеке...
 Это смотри сколько тебе инфы надо будет засунуть в стек: весь массив и еще индексы на отрицательные элементы. ИМХО я на месте препода да же разбираться не стал бы и сразу бы понял, что человек вообще нихрена не понимает, зачем стек нужен. Формально моя задача звучит так:Составить программу, выполняющую обработку массива, аналогично заданию предыдущей работы, но оформленной в виде "ближней" процедуры, параметры в которую передаются через стек.
 
 
 Вот что я тебе предложил, это самый верный результат и соответствует заданию на сто процентов. |  
						| 
								|  |  
								| « Последнее редактирование: 06-10-2009 15:09 от Sel » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #70 : 04-10-2009 18:03 »  |  | 
 
 Anarky, делай проще. надо взять из стека элементы, сложить отрицательные, а для этого надо указать где они хранятся в стеке... Тогда передавай в функцию суммирования два значения, одно аккумулятор (это где накапливается сумма) и второе значение это элемент массива. Если элемент отрицательный то суммируй его с аккумулятором если нет то не суммируй. Результат возвращай через AX. И так для всех элементов. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #71 : 04-10-2009 18:04 »  |  | 
 
 я бред написал! массив из 8ми элементов, отрицательные сложить, используя подпрограмму, данные должны передаваться через стек!  |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #72 : 04-10-2009 18:07 »  |  | 
 
 я бред написал! массив из 8ми элементов, отрицательные сложить, используя подпрограмму, данные должны передаваться через стек! 
 Это тогда соответствует первому предложенному варианту, т.е. вызывается функция которой передается два значения и она их суммирует. Основной цикл вызывает при необходимости данную функцию. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #73 : 04-10-2009 18:15 »  |  | 
 
 надо вставить в мою рабочую программу подпрограмму, в которой складываются значения? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #74 : 04-10-2009 18:16 »  |  | 
 
 Давайте вернемся чуть назад. Хочу таки пояснить, что тут происходило со стеком.   push -3push -2
 push -1
 push 0
 push 1
 push 2
 push 3
 push 4
 
В стек помещены данные. В стек помещен адрес возврата. сама подпрограмма: sum:push bp
 mov bp,sp
 mov ax, [bp+2]
 cmp ax,0            ; сравниваем ax с нулем
 pop bp ; вкидывает из стека проверенный элемент
 jb go
 
Бестолковое перемешивание стека. вызываю подпрограмму: (повтор)Увеличение SP на 2. Очень странно - ты же 8 слов на стек положил - 16 байт! 
 На практике массив не загружают в стек (как это пояснил Serg79), но если параметров будет немного, то можно и через стек, но нужно обязательно передать в подпрограмму число элементов. Это получается подпрограмма с переменным числом параметров. start:push -3
 push -2
 push -1
 push 0
 push 1
 push 2
 push 3
 push 4
 push 8 ; число параметров
 call sum
 add sp, 18
 ret
 
 sum:
 push bp
 mov bp, sp
 mov cx, [bp + 4] ; загружаем количество параметров
 mov si, 6 ; начальное смещение
 xor ax, ax ; инициализация суммы
 sum_1:
 add ax, [bp + si]
 add si, 2
 loop sum_1
 pop bp
 ret
 
Но лучше этого избегать: данные хранить в другом месте и передавать в параметрах указатель на их начало и количество элементов. .dataargc  dw 8
 args  dw -3, -2, -1, 0, 1, 2, 3, 4
 
 .code
 start:
 push [offset args]
 push [offset argc]
 call sum
 add sp, 4
 ret
 
 sum:
 push bp
 mov bp, sp
 mov cx, [bp + 4] ; загружаем количество параметров
 mov si, [bp + 6] ; загружаем указатель на данные
 xor ax, ax ; инициализация суммы
 sum_1:
 add ax, [si]
 add si, 2
 loop sum_1
 pop bp
 ret
 
Собственно, вот готовый код. Попробуй просто вставить в него проверку на отрицательные значения. |  
						| 
								|  |  
								| « Последнее редактирование: 04-10-2009 18:35 от RXL » |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #75 : 04-10-2009 18:17 »  |  | 
 
 надо вставить в мою рабочую программу подпрограмму, в которой складываются значения?Anarky
 , ты меня удивляешь. Очевидно же . |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #76 : 04-10-2009 18:59 »  |  | 
 
 Для вас очевидно! А для меня тут многое непонятно. А черт его знает... .dataargc  dw 8
 args  dw -3, -2, -1, 0, 1, 2, 3, 4
 
 .code
 start:
 push [offset args]
 push [offset argc]
 call sum
 add sp, 4 ???? закрытие параметров (что это значит??????)
 ret
 
 sum:
 push bp
 mov bp, sp
 mov cx, [bp + 4] ; загружаем количество параметров ???? что это за параметры? и почему 4 прибавляем????
 mov si, [bp + 6] ; загружаем указатель на данные ???? вроде понятно, что это указатель, но почему +6
 xor ax, ax ; инициализация суммы ?????? это обнуление AX?????
 sum_1:
 add ax, [si] ;!!!!!!! тут понятно, что в AX помещаем
 add si, 2    ;!!!!!!! следующий элемент, 2 потому что DW
 loop sum_1
 pop bp
 ret
 
Объясните пожалуйста! Код это хорошо, но я в нем разобраться хочу   |  
						| 
								|  |  
								| « Последнее редактирование: 06-10-2009 15:06 от Sel » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #77 : 04-10-2009 19:09 »  |  | 
 
 Anarky честно сказать, такие вещи да же объяснять не хочется. Если ты в этом коде самостоятельно разобраться не можешь, то я не знаю чем тебе помочь. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #78 : 04-10-2009 19:10 »  |  | 
 
 в универе это нах никому не надо, преподу тем более... покажу: посмотрит, отметит...
 а я ЗНАТЬ хочу!!!
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #79 : 04-10-2009 19:12 »  |  | 
 
 Anarky, Ты разберись что помещается в стек перед вызовом данной функции и что помещается в стек при выполнении команды call, тогда ты все поймешь. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #80 : 04-10-2009 19:13 »  |  | 
 
 Anarky, ахренеть. Ты в универе учишься а с литературой работать не можешь. Ты уж извини, но исходя из твоих вопросов я думал что ты в школе учишься. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #81 : 04-10-2009 19:21 »  |  | 
 
 у меня никогда не было ассемблера, литературы целый вагон, читаю конечно! |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #83 : 04-10-2009 19:25 »  |  | 
 
 у меня никогда не было ассемблера, литературы целый вагон, читаю конечно!Anarky
 , поэтому я тебе и говорю: разбирайся и читай учебники. Что толку если я тебе скажу что в функции sum в CX помещается счетчик а в SI указатель на начало массива, от этого что либо измениться или ты больше понимать станешь? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #84 : 04-10-2009 19:31 »  |  | 
 
 Anarky, замечательно! Хочешь знать - учи и спрашивай конкретику - мы поможем понять.     push [offset args]push [offset argc]
 call sum
 add sp, 4 ???? закрытие параметров (что это значит??????)
 ; Закрытие? Скорее освобождение места.
 ; Внимательно читаем описание команды push в справочнике
 ;  и чрезвычайно внимательно вглядываемся в 4 (всего!) команды.
 
 mov cx, [bp + 4] ; загружаем количество параметров ???? что это за параметры? и почему 4 прибавляем????
 mov si, [bp + 6] ; загружаем указатель на данные ???? вроде понятно, что это указатель, но почему +6
 ; б##... Ниже подробно опишу.
 
 xor ax, ax ; инициализация суммы ?????? это обнуление AX?????
 ; Да. В AX храним сумму. Здесь - инициализация нулем.
 ; XOR сам на себя - классический способ для замены присвоения константы.
 
 add ax, [si] ;!!!!!!! тут понятно, что в AX помещаем
 ; Не помещаем! Складываем и помещаем!
 
 add si, 2    ;!!!!!!! следующий элемент, 2 потому что DW
 ; Именно! :)
 
Значит так. Говорим только о 16-битных командах, чтобы не путаться и не отвелекаться. 1. Регистр SP указывает на текущую вершину стека - на последнее помещенное в него значение. 2. Команды, работающие со стеком, оперируют размерами, кратными 2. При помещении значения на стек SP уменьшается на размер помещенного значения. Если не рассматривать call/ret far, прерывания и pusha/popa, то во всех остальных случаях на стек помещается или с него забирается 2-байтовое значение (слово). 3. Команда push помещает одно слово (DW) в стек.  4. Команда pop забирает одно слово со стека.  3. Команда call (near) помещает в стек адрес возврата из подпрограммы - тоже одно слово. 4. Команда ret (near) забирает одно слово - адрес возврата. При входе в подпрограмму sum, на стеке у нас расположены: 1. адрес возврата - [SP] 2. первый параметр - [SP + 2] 3. второй параметр - [SP + 4] После того, как мы делаем push bp, получаем: 1. BP - [SP] 2. адрес возврата - [SP + 2] 3. первый параметр - [SP + 4] 4. второй параметр - [SP + 6] После чего мы присваиваем текущее значение SP регистру BP и используем его для доступа к параметрам. Оттуда [BP + 4] и [BP + 6]. Теперь понятно? |  
						| 
								|  |  
								| « Последнее редактирование: 04-10-2009 19:33 от RXL » |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Serg79 | 
								|  | « Ответ #85 : 04-10-2009 19:36 »  |  | 
 
 Радуйся Anarky , что есть такие люди как RXL . Которые готовы помочь даже таким бездельникам как ты. P.S. не обижайся Anarky , я знаю ты разберешься в этом и для тебя это станет очевидным .   |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #86 : 04-10-2009 20:03 »  |  | 
 
 я себе стек представлял как обойму в пистолете (не смейтесь) достаем патрон, если холостой выбрасываем)))))) если боевой: кладем в карман, в AX)))))) потом смотрим сколько в кармане))))) как вам сравнение? а тут оказывается мы ничего не достаем, ничего никуда не деваем, просто указываем откуда начинаются данные и с ними работаем   А вы ребята молодцы, вам спасибо, респект и уважуха))) завтра попробую все в одну кучу собрать и заставить работать! |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #87 : 04-10-2009 20:39 »  |  | 
 
 Anarky, карман у нас не резиновый и потому в нем только одно значение. В целом, сравнение неплохое. Только стек здесь не имеет конца: SP - это просто смещение в сегменте SS и когда SP дойдет до любого края, он перейдет на другую сторону.
 Все данные хранятся в памяти - стек в том числе - вопрос только как к ним подступиться.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| Anarky 
								Постоялец    Offline | 
								|  | « Ответ #88 : 05-10-2009 06:58 »  |  | 
 
 RXL а почему мы не можем просто указать  мы пишем в подпрограмме sum после push: 1. BP - [SP] ; команда push поместила слово  2. [SP + 2]  ; адрес возврата 3. [SP + 4]  ; указатель массива  4. [SP + 6]  ; элемент в массиве 5. add si, 2 ; просматриваем следующий элемент массива |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #89 : 05-10-2009 07:36 »  |  | 
 
 Anarky, откуда твоя подпрограмма знает, сколько элементов в массиве? Хадр-кодед - это большое зло. Значит может узнать только из параметров. мы пишем в подпрограмме sum после push: 1. BP - [SP] ; команда push поместила слово  2. [SP + 2]  ; адрес возврата 3. [SP + 4]  ; указатель массива  4. [SP + 6]  ; элемент в массиве 5. add si, 2 ; просматриваем следующий элемент массиваНеверно! 1. push [offset args] +0 указатель 2. push [offset argc] +0 размер массива +2 указатель 3. call sum +0 адрес возврата +2 размер массива +4 указатель 4. push bp +0 сохраненное значение BP +2 адрес возврата +4 размер массива +6 указатель Напоминаю про соглашение о порядке помещения аргументов в стек! Стиль Си: push в обратном порядке, а в памяти они в прямом порядке. Стиль Паскаль: push в прямом порядке, а в памяти они в обратном порядке. Стиль pascal исключает возможность иметь переменное число параметров, предусмотренное в языке Си. В примере я использовал стиль Си. |  
						| 
								|  |  
								| « Последнее редактирование: 05-10-2009 07:38 от RXL » |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	|  |