首页 > 汇编语言 > 汇编与C语句 阅读:57,774

C语句与汇编

学习了汇编语言之后,就需要将常用的C语言代码结构与相应的汇编语言联系起来。这样就可以在分析汇编语言的时候,明白它的意思。C语言中函数过程的调用,循环语句,条件语句,结构体与数组的访问都有对应的特定的汇编语言结构。下面来分别分析这些特定的结构。

有些在C层面不好理解的代码,只要分析下它的汇编,就很容易明白其中的原理了,比如之前学习的函数的调用约定,函数的传参等。

4.1.1循环语句(for,while,do-while)与汇编

For循环语句的汇编代码:

C代码:

for(int i=0;i<10;i++)

{

}

汇编代码:

i=0;

jmp A;

B:

i++

A:

cmp i, 0ah

jge OUT;

.....

jmp B;

 

OUT:

While循环语句的汇编代码:

while(i<10)

{

       i++;

}

A:

cmp i,0ah

jge OUT;

......

i++;

 

jmp A;

OUT:

4.1.2if语句与汇编

if-else语句汇编代码:

if(i>0)

{

    

}

else

{

    

}

汇编代码:

cmp i,0

jle ELSE;

....

jmp OUT;

 

 

ELSE:

....

 

OUT:

Switch语句的汇编代码:

switch(value)

{

case 1:

    

    break;

case 2:

    

    break;

default:

 

}

switch:

cmp value, 1

je A;

cmp value, 2

je B;

jmp DEFAULT;

A:

...

jmp OUT

B:

...

jmp OUT

DEFAULT:

...

OUT:

4.1.3数组访问与汇编

数组访问的汇编代码如下:

 

int g_a[100]={100,99,98,97,0};

      

for(int i = 0; i<100;i++)

0093149E  mov         dword ptr [i],0

009314A5  jmp         wmain+30h (9314B0h)

009314A7  mov         eax,dword ptr [i]

009314AA  add         eax,1

009314AD  mov         dword ptr [i],eax

009314B0  cmp         dword ptr [i],64h

009314B4  jge         wmain+46h (9314C6h)

{

              g_a[i]=10;

009314B6  mov         eax,dword ptr [i]

009314B9  mov         dword ptr g_a (937000h)[eax*4],0Ah //数组首地址+i*4

}

4.1.4结构体访问与汇编

结构体中成员访问汇编代码如下:

typedef struct _S

{

       int val;

       char ch;

}S,*PS;

S g_s1;

 

g_s1.val=100;

0030149E  mov         dword ptr [g_s1 (307344h)],64h //结构体首地址+偏移量(0

 

g_s1.ch='A';

003014A8  mov         byte ptr [g_s1+4 (307348h)],41h//结构体首地址+偏移量(4)

4.1.5结构体数组与汇编

结构体数组成员访问汇编代码如下:

typedef struct _S

{

       int val;

       char ch;

}S,*PS;

S g_as[100]={{0}};

 

for(int i = 0;i<100;i++)

00FA149E  mov         dword ptr [i],0

00FA14A5  jmp         wmain+30h (0FA14B0h)

00FA14A7  mov         eax,dword ptr [i]

00FA14AA  add         eax,1

00FA14AD  mov         dword ptr [i],eax

00FA14B0  cmp         dword ptr [i],64h

00FA14B4  jge         wmain+51h (0FA14D1h)

{

              g_as[i].val=100;

00FA14B6  mov         eax,dword ptr [i]

00FA14B9  mov         dword ptr g_as (0FA7328h)[eax*8],64h //数组首地址+i*8+偏移(0

              g_as[i].ch='Z';

00FA14C4  mov         eax,dword ptr [i]

00FA14C7  mov         byte ptr g_as+4 (0FA732Ch)[eax*8],5Ah //数组首地址+i*8+偏移(4)

}

4.1.6 i++与汇编

C语句中的i++对应的汇编语句如下:

int i = 0;

00FC14D4 mov dword ptr [i],0

i++;

00FC14DB mov eax,dword ptr [i]

00FC14DE add eax,1

00FC14E1 mov dword ptr [i],eax

 

可见,对于在C语言中的一条语句,在汇编层也有可能是多条汇编指令组成。因此,即使在单核多线程环境下,i++也不是多线程安全的,因为它不是原子操作,因为一个线程执行了i++某一条汇编指令,CPU的时间片就有可能用完了,发生了切换,而另外一个线程切换进来之后,又开始从头开始执行i++的汇编指令,因此造成多线程不一致性。

因此,要保证i++语句的多线程安全,要么使用锁机制,要么使用原子操作:比如Windows平台的InterLockedIncrement()函数或者Linux平台的atomic_t类型以及相关的操作。

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注