Invoke ExitProcess,0
main endp
End main
SIZER equ 15
REZbuf byte SIZER dup (?)
Смысл инструкции cmp в том, что из левого операнда как бы вычитается правый операнд. При этом флаги устанавливаются так, как будто произошло вычитание, сами же операнды не меняются. Поэтому эта инструкция находится в связке с флагом нуля. je – Z flag.
Loop – уменьшает на единицу ecx, проверяет не стал ли он равен нулю, если стал равен нулю, то переходит к следующей за ним инструкции если нет, то переходит в начало цикла. mov ecx,10 – значит 10 раз выполнится 10 9 8 7 6 5 4 3 2 1 , если 0, то выполнится 10000h раз для 4-х разрядного. Такой цикл выполняется хотя бы один раз.
mov ecx,10
mov edi,1
Lab_:
push ecx
invoke wsprintf,addr ConvBuf,addr Frm,edi
invoke WriteConsole,Hnd,addr ConvBuf, sizeof ConvBuf,addr WrittenCh,NULL
pop ecx
inc edi
loop Lab_
Windows API сохраняют только значения регистров ebx, edi, esi, ebp
.data? – не определены данные и ! они не занимают место в исполняемом файле.
Любой символ от 0 до 9 получается прибавлением 48 к цифре.
Доступ к элементам массива можно рассматривать как расширенную косвенную адресацию т.к. инструкции
mov PrimeNumbers[edi], bx и mov [PrimeNumbers+edi], bx равны. Метка в квадратных скобках хороша так же, как и без них. В любом случае ассемблер считает, что это адрес компьютерной памяти.
Деление беззнаковых операндов
В качестве операнда указывается делитель, который может хранится как в регистре, соответствующего ему размеру, так и в памяти.
div bl(255max) ax :bl - al %ah
div bx(65535max) dx:ax :bx - ax %dx
div ebx(2^32 -1max) edx:eax :ebx - eax %edx
Деление операндов со знаком
В качестве операнда указывается делитель, который может хранится как в регистре, соответствующего ему размеру, так и в памяти.
idiv bl(255max) ax :bl - al %ah
idiv bx(65535max) dx:ax :bx - ax %dx
idiv ebx(2^32 -1max) edx:eax :ebx - eax %edx
xor eax,eax
mov ax,0FFFFh
mov ecx,0FFh; 255+1=100h
div cl
(max)*(max)=(max)
A * B = C
C/A=B т.к. разрядность под С позволяет вместить большее число, чем произведение максимально возможных значений A и B, то в этом случае возникает целочисленное переполнение
Условие возможности деления C <= A(max)*B(max)
Если заранее известно А и С и надо найти B, то необходимо проверить A()*B(max)<=C
1111 1110 0000 0001 - ax max 65025=255*255
1111 1111 - div cl если < то будет переполнение
1111 1111 - al
0000 0000 - %ah
Логическое И проделывается над каждой парой битов.
Четность и нечетность определяется самым младшим битом, если единица, то число нечетно.
Свойство логического И легко использовать для выделения младшего бита числа при помощи маски.
mov ecx,3 ;ecx = k
For1:
mov ebx,2 ; j=2
For2:
mov edi,ecx ; check
and edi,01h ; check
cmp edi,00h ; check
je Break ; check
xor edx,edx
mov eax,ecx
div ebx
Операция test ah, 00000001b не затрагивает приемник-операнд и подобна следующей группе:
And ah, 00000001b
Cmp ah,0
For2:
test ecx,01h ; check
je Break ; check
xor edx,edx
mov eax,ecx
Test ah,00000001b притворяется что делает and
jz(je) четное
Test ah,00000001b
Четное Делится на четыре XXXXXXXXXXXXXXX0 Jz(Je) |
Не четное Не делится на четыре на цело XXXXXXXXXXXXXXXXXXXXXXX1 Jnz(jne) |
; Conditional Jump
test cl, cl ; set ZF to 1 if cl == 0
je 0x804f430 ; jump if ZF ==1
;or
test eax,eax ; set SF to 1 if eax < 0 (negative)
js error ; jump if SF == 1
Фрагмент, который гасит правый бит в регистре eax (для быстрого подсчета количества единичных бит в регистре)
Mov ebx,eax
Dec ebx
And eax,ebx
xxxxx1000
xxxxx0111
and
крайний правый бит погаснет остальные останутся прежними
.code
Start:
mov eax,11223344h ; 1 0001 0010 0010 0011 0011 0100 0100
mov ebx,11223343h ; 1 0001 0010 0010 0011 0011 0100 0011
and eax,ebx ; 1 0001 0010 0010 0011 0011 0100 0000
ИЛИ удобна для объединения нескольких условий которые закодированы отдельными битами
Если младший бит одного регистра, установленный в единицу, показывает, что число делится на два, а следующий по значимости бит другого регистра говорит о том, что число делится на 3, то после операции ИЛИ над обоими регистрами станет ясно, что число делится и на 3 и на 2.
-------
or eax,ecx ; проверка когда оба операнда будут равны нулю.
jnz
--------
Проверка на делимость на четыре нацело. (в битах 0 и 1 записан остаток от деления на 4 и число делится на 4 если этот остаток(биты0и1) равен нулю) test eax,03h
mov eax,Num
cmp eax,0
je Exit
test eax,03h
je LAB_Yes
xor выделяет различия .
xor eax,0FFFFFFFFh
инвертирует биты ~ not eax ; но!! - это не NEG!!!
xor EAX,EBX
xor eax,ebx - эта пара инструкций ничего не делает (шифровка и дешифровка)
Что справедливо для отдельных битов, то справедливо и для регистра в целом. Поэтому нужно рассмотреть четыре варианта: 0-0 0-1 1-0 1-1
Горизонтальная стрелка показывает, какой регистр изменится в результате операции. Вертикальная указывает на результат. В квадратах показаны конечные значения регистров.
eax ebx
1 <- 1
|
0 <- 1
|
1
xor eax,ebx
xor ebx,eax
xor eax,ebx тройка – обмен содержимым регистров
