汇编语言3
<h1 id="汇编语言学习003">汇编语言学习003</h1><p>学习汇编语言的目的,其实更多是为了学习逆向,因此汇编语言大致就学了这些就要过去了。</p>
<p>下面是一些命令的用法</p>
<table>
<thead>
<tr>
<th>指令名称</th>
<th>指令用法</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>test</td>
<td>testreg,00000001</td>
<td>逻辑与add命令相同【按位相同为1才为1】,不同点是不会将结果写入寄存器,所以reg中的值不会改变但是会修改标志位,结果为0,则zf=0</td>
</tr>
<tr>
<td>cmp</td>
<td>cmp o1,o2</td>
<td>用于比较整数和字符,会修改标志位;o1>o2,zf=0,cf=0;o1<o2,zf=0,cf=1;o1=o2,zf=1,cf=0</td>
</tr>
<tr>
<td>jcc系列</td>
<td></td>
<td></td>
</tr>
<tr>
<td>loop</td>
<td>loop l1</td>
<td>l1表示将要跳到的地址位置;ecx!=0就循环</td>
</tr>
<tr>
<td>loopz</td>
<td>loopz l1</td>
<td>ecx!=0&&zf==1;一般用于加减法导致的符号位</td>
</tr>
<tr>
<td>loope</td>
<td>loope l1</td>
<td>ecx!=0&&zf==1;一般用于cmp导致的符号位</td>
</tr>
<tr>
<td>loopnz</td>
<td>loopnz l1</td>
<td>ecx!=0&&zf==0</td>
</tr>
<tr>
<td>loopne</td>
<td>loopne l1</td>
<td>ecx!=0&&zf==0</td>
</tr>
</tbody>
</table>
<p>下面是关于选择结构</p>
<pre><code>.if eax>esi
inc eax
.else
inc esi
.endif
</code></pre>
<p>下面是while循环</p>
<pre><code>.while ecx > 0
mov esi,esp
dec ecx
.endw
</code></pre>
<p>下面是do-while</p>
<pre><code>mov eax,2
xor ecx,ecx
.repeat
mov esi,eax
inc eax
add ecx,1
.until ecx > 3
</code></pre>
<p>逻辑移位及算术移位</p>
<pre><code>在左移中,逻辑移位与算术移位相同,都是在低位【最右端】补0
在左移中,逻辑移位在高位【最左端】补0
算术移位在高位【最右端】补符号位
</code></pre>
<table>
<thead>
<tr>
<th>指令</th>
<th>指令用法</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td>shl</td>
<td>shl eax,1</td>
<td>逻辑左移</td>
</tr>
<tr>
<td>shr</td>
<td>shr eax,1</td>
<td>逻辑右移</td>
</tr>
<tr>
<td>sal</td>
<td>sal eax,1</td>
<td>算术左移</td>
</tr>
<tr>
<td>sar</td>
<td>sar eax,1</td>
<td>算术右移</td>
</tr>
<tr>
<td>rol</td>
<td>rol eax,1</td>
<td>循环左移</td>
</tr>
<tr>
<td>ror</td>
<td>ror eax,1</td>
<td>循环右移;左边的最低位移到右边的最高位</td>
</tr>
<tr>
<td>rcl</td>
<td>rcl eax,1</td>
<td>带进位的循环左移</td>
</tr>
<tr>
<td>rcr</td>
<td>rcr eax,1</td>
<td>带进位的循环右移;cf也会进入移位的单元</td>
</tr>
<tr>
<td>shld</td>
<td>shld o1,o2,立即数</td>
<td>双精度左移;第一个数不能是byte类型,立即数是几,o2中的几位数就好用来补充o1的低位</td>
</tr>
<tr>
<td>shrd</td>
<td>shrd o1,o2,o3</td>
<td>双精度右移</td>
</tr>
</tbody>
</table>
<p>乘法与除法</p>
<pre><code>无符号乘法
mov a1,5h
mov bl,10h
mul bl ;只有一个参数,代表乘数,被乘数由系统默认
;当乘数位数所在寄存器位数为8:被乘数存储在al中;为16:被乘数存储在ax;为32:被乘数存储在eax
;结果也由系统默认存储
;8*8:结果放在ax中
;16*16:结果的高16位放在dx中,低16位放在ax中
;32*32:结果的高32位放在edx中,低32位放在eax中
有符号乘法
mov eax,12345h
mov ebx,10000h
imul eax,ebx ;结果第一个操作数所在寄存器中,此时of=1;eax=23450000h
imul edx,eax,10000h;第三个操作数一定是立即数,此时,后二者的积存放在第一个寄存器中;edx=23450000h
无符号除法
mov ax,101
mov bl,10
div bl ;只有一个参数,代表除数,被除数由系统默认
;当除数位数所在寄存器位数为8:被除数存储在ax中;为16:被除数存储在dx:ax;为32:被除数存储在edx:eax
;结果也由系统默认存储
;16div8:商放在al中,余数放在ah中
;16div16:商放在ax中,余数放在dx中
;32div32:商放在eax中,余数放在edx中
mov dx,0000h
mov ax,007fh
mov bx,100h
div bx ;ax=00h;dx=7fh
xor edx,edx
mov eax,0000ffffh
mov ebx,0000fff0h
div ebx ;eax=00000001h;edx=0000000fh
</code></pre>
<p>扩展加法和减法</p>
<pre><code>;adc 扩展加法
xor edx,edx
mov al,0ffh
add al,0ffh ;al=fe---- cf=1
adc dl,0 ;dl = dl+0+cf=1=01h
;sbb扩展减法
mov edx,8
mov eax,1
sub eax,2 ;eax=0ffffffffh cf=1
sbb edx,0 ;edx = edx-0-1=7
通过以上减法计算,就会得到一个结果
0000000800000001h - 0000000000000002h = 00000007ffffffffh ;64位数的减法
</code></pre>
<p>ASCII之间的运算</p>
<p>如3344----->33 33 34 34</p>
<p>压缩十进制</p>
<p>如3344----->03 03 04 04</p>
<pre><code>;加法 aaa
mov ah,0;方便观察
mov al,'3'
add al,'8'
aaa
or ax,3030h;加法都是与3030h做或运算
;减法 aas
mov ah,0
mov al,'8'
sub al,'3'
aas
pushf
or al,30h ax值0035h
popf
;乘法---压缩10进制
mov al,3
mov bl,4
mul bl;ax=0012
aam ;ax值0102h
push 0
</code></pre>
<p>过程相关的伪指令</p>
<pre><code>INVOKE
CALL
</code></pre>
<p>字符串相关</p>
<pre><code>传送、比较、扫描、保存、加载
;传送: MOVSB MOVSW MOVSD/ byteworddword
string1 db "hello world",0
string2 byte 12 dup(?)
cld
mov esi,offset string1
mov edi,offset string2
mov ecx,12
rep movsb ;字符串复制
mov eax,eax
;比较: CMPSB CMPSW CMPSD CMP / STRING BYTE
val1 dword 7000h
val2 dword 6000h
cld
l1:
mov esi,offset val1
mov edi,offset val2
cmpsd
ja l1
mov eax,eax
;扫描: SCASB SCASW SCASD
string db "ABCDEF",0
l1:
mov edi,offset string
mov al,'a'
mov ecx,sizeof string
cld
repne scasb
jnz l1
mov eax,eax
;保存 :STOSB STOSW STOSD
string db 100 dup(?)
mov al,0ffh
mov edi,offset string
mov ecx,100 ;运行100次
cld
rep stosb ;将al的值重复保存
mov eax,eax
;加载 LODSB LODSW LODSD;从esi指针加载到AL,AX,EAX
</code></pre>
<p>结构体与宏定义</p>
<pre><code>;结构体
.data
ni struct
val1 dword ?
val2 dword ?
ni ends
stu ni <>
.code
mov stu.val1,1
mov eax,stu.val1
mov eax,eax
;宏定义
.data
me MACRO charc
mov eax,charc
ENDM
.code
ni 9 ;eax=9
</code></pre>
<p>浮点数</p>
<pre><code>浮点数运算指令:F+普通运算指令
</code></pre>
<p>内联汇编</p>
<pre><code>C语言中使用汇编语言
int main(void){
_asm mov eax,1
_asm mov esi,eax
return 0;
}
int main(void){
int val = 0;
char a[] = {'h','e','l','l','o'}
_asm{
mov eax,val ;内部可以用外部的变量
mov esi,eax
;赋值为字符串
lea esi,a
}
}
</code></pre>
<p>汇编语言暂时停在此处,后再补充。</p><br><br>
来源:https://www.cnblogs.com/youxunle/p/14022547.html
頁:
[1]