Ассемблер для чайников. (#2) (C) Михаил Спицын 1995 ________________________________ Флаги Регистр "F" процессора назы- вается флаговым. Что это такое ? Флаг - это переменная, кото- рая может иметь два состояния, - установлено (равно единице) и сброшено (равно нулю). Поэтому регистр "F" можно рассматривать как набор восьми флаговых битов. Мы можем использовать только четыре из них: флаг нуля, флаг переноса, флаг знака и флаг чет- ности-переполнения. Арифметические операции. Арифметика - наука весьма и весьма полезная, мы постоянно что-нибудь считаем: складываем, отнимаем, делим, умножаем. О том, как сделать это на ассемб- лере, мы сейчас и поговорим. Начнем мы с самого простого, прибавим единицу к чему-нибудь, например к регистру "А": ******************************** LD A,NUBER INC A RET ******************************** Как видите, это очень просто, для этого существует команда "INC" - инкремент (увеличение на единицу), после нее идет опе- ранд, т.е. какой-нибудь регистр или регистровая пара: ******************************** INC A INC HL INC H INC DE INC E INC IY INC E INC (HL) INC (IX+N) INC (IY+N) ******************************** Если Вам нужно увеличить на единицу какую-либо ячейку памя- ти, то следует поступить так: ******************************** LD HL,ADDRES LD IX,ADDRES INC (HL) INC (IX+0) RET RET ******************************** Первый вариант работает бы- стрее и удобен, если работа идет с одной ячейкой памяти, но если вы работаете в таблице, то это не экономично и некрасиво. Срав- ните: нам нужно увеличить на единицу первый, пятый и десятый байты в таблице: ******************************** LD HL,TABL+1 LD IX,TABL INC (HL) INC (IX+1) LD HL,TABL+5 INC (IX+5) INC (HL) INC (IX+10) LD HL,TABL+10 RET INC (HL) RET ******************************** Все, что сказано выше о уве- личении на единицу, справедливо и для декремента, т.е. для уменьшения на единицу: ******************************** DEC A DEC HL DEC L DEC IX DEC H DEC DE DEC E DEC BC DEC D DEC IY DEC C DEC IX DEC B DEC (HL) DEC (IX+N) DEC (IX+N) ******************************** А теперь предположим, что нам надо увеличить регистр "A" не на единицу, а скажем, на десять: ******************************** LD A,NUMBER ADD A,10 RET ******************************** Складывать можно регистр "A" с числом и другими регистрами и с ячейкой памяти, адресованной регистровыми парами "HL", "IX" и "IY". Так же можно складывать регистровые пары с "HL", "IX" и "IY". (PureBasic - файловая система) ******************************** ADD A,N ADD A,(HL) ADD A,A ADD A,(IX+N) ADD A,B ADD A,(IY+N) ADD A,C ADD HL,HL ADD A,D ADD HL,BC ADD A,E ADD HL,DE ADD A,H ADD HL,SP ADD IX,IX ADD IX,BC ADD IX,DE ADD IX,SP ******************************** Как видите, набор команд дос- таточно велик. При выполнении этой команды может возникнуть ошибка: ******************************** LD A,45 LD B,230 ADD A,B RET ******************************** Сумма "А" и "В" превысило 255 и поэтому в "А" окажется не 275, а 20 (регистр "А" не резиновый); чтобы мы знали, что произошло переполнение, процессор устанав- ливает флаг переноса в единицу. Остается только проверить его. Подобно тому, как у "INC" есть "DEC", у "АDD" тоже есть "парочка", это "SUB", и у нее имеются свои особенности. Коман- да "SUB" работает только с ре- гистром "А", поэтому при написа- нии мнемоники этой команды "А" опускается: ******************************** SUB N SUB C SUB A SUB H SUB B SUB D SUB E SUB (HL) SUB (IX+N) SUB (IY+N) ******************************** Команда влияет на флаг пере- носа так же, как и "АDD". Кроме пары команд "ADD" и "SUB" существуют еще одна пара. Команды "ADC" и "SBC" работают с учетом флага переноса, т.е. при сложении или вычитании к результату добавляется (отнима- ется) значение флага переноса. Для установки флага переноса есть две спецкоманды - это "SCF" и "CCF". "SCF" - установить флаг переноса в единицу. "CCF" - ус- тановить флаг переноса в ноль. ******************************** ADC A,N SBC A,N ADC A,A SBC A,A ADC A,H SBC A,H ADC A,L SBC A,L ADC A,D SBC A,D ADC A,E SBC A,E ADC A,B SBC A,B ADC A,C SBC A,C ADC A,(HL) SBC A,(HL) ADC A,(IX+N) SBC A,(IX+N) ADC A,(IY+N) SBC A,)IY+N) ADC HL,HL SBC HL,HL ADC HL,BC SBC HL,BC ADC HL,DE SBC HL,DE ADC HL,SP SBC HL,SP ******************************** А теперь примеры работы ко- манд "ADC" и "SBC" : ******************************** LD A,10 LD A,10 LD B,5 LD B,5 CCF CCF SBC A,B ADC A,B RET RET A=5 B=5 A=15 B=5 ******************************** Вместо двух команд "CCF" и "SBC A,B" можно поставить прос- то "SUB B", результат будет тот же. ******************************** LD A,10 LD A,10 LD B,5 LD B,5 SCF SCF SBC A,B ADC A,B RET RET A=4 B=5 A=16 B=5 ******************************** Как видно из результатов, флаг переноса значительно влияет на результат операции. При вычи- тании он отнимается от результа- та, а при сложении прибавляется к результату. По операциям сложения и вычи- тания рассказано почти все, те- перь мы поговорим о делении и умножении. К сожалению SPECCY не имеет команд деления и умноже- ния, но эти команды можно соста- вить из нескольких других. Нап- ример, нам нужно перемножить со- держимое двух регистров - "А" и "C" : ******************************** LD A,10 LD C,5 LD B,A XOR A LOOP ADD A,C DJNZ LOOP RET ******************************** В примере встречаются две но- вые команды - "XOR A" и "DJNZ LOOP". "XOR A" обнуляет регистр "А", а команда "DJNZ LOOP" пов- торяет все команды, с команды, помеченной меткой (например "LOOP"), до команды "DJNZ" (пос- ле нее должна стоять та же мет- ка, что и в начале цикла); число повторений задается в регистре "В". Используя то, что умножение M на N - это сложение числа М само с собой N раз, Вы можете разобратся с примером, приведен- ным выше. Можно использовать это свой- ство и для деления. Попробуй- те сделать это сами. В следующий раз поговорим о командах сравнения и работы с битами. ________________________________