c->asm tc内部机制
2007-05-04 16:42
288 查看
我们用TC编写一段简单的代码!看看生成的汇编代码是什么!
#include "stdio.h"
sum(int x,int y)
...{
return x+y;
}
int aa;
int bb=1;
main()
...{
int a=1;
int b=2;
int c=sum(a,b);
printf("c=%d",c);
}
好,我们知道汇编里函数内的变量是自动变量,也就是通过栈来实现的,很容易忽略的就是MAIN函数也是函数,代码中的A,B变量也是自动变量.先生成汇编代码TCC -S 文件
ifndef ??version
?debug macro
endm
endif
?debug S "shiyan.c"
_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP,ss:DGROUP
_TEXT ends
_DATA segment word public 'DATA'
d@ label byte
[email=d@w]d@w[/email] label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
[email=b@w]b@w[/email] label word
?debug C E9A77AA4360873686979616E2E63
?debug C E957A7972615433A5C54435C494E434C5544455C737464696F2E68
?debug C E957A7972616433A5C54435C494E434C5544455C7374646172672E+
?debug C 68
_BSS ends
_TEXT segment byte public 'CODE'
; ?debug L 2
_sum proc near
push bp
mov bp,sp
; ?debug L 4
mov ax,word ptr [bp+4]
add ax,word ptr [bp+6]
jmp short @1
@1:
; ?debug L 5
pop bp
ret
_sum endp
_TEXT ends
_DATA segment word public 'DATA'
_bb label word
dw 1
_DATA ends
_TEXT segment byte public 'CODE'
; ?debug L 8
_main proc near
push bp
mov bp,sp
sub sp,2
push si
push di
; ?debug L 10
mov si,1
; ?debug L 11
mov di,2
; ?debug L 12
push di
push si
call near ptr _sum
pop cx
pop cx
mov word ptr [bp-2],ax
; ?debug L 13
push word ptr [bp-2]
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
pop cx
@2:
; ?debug L 14
pop di
pop si
mov sp,bp
pop bp
ret
_main endp
_TEXT ends
_BSS segment word public 'BSS'
_aa label word
db 2 dup (?)
_BSS ends
?debug C E9
_DATA segment word public 'DATA'
s@ label byte
db 99
db 61
db 37
db 100
db 0
_DATA ends
_TEXT segment byte public 'CODE'
extrn _printf:near
_TEXT ends
public _main
public _sum
public _bb
public _aa
end
代码比起C的代码要多很多,但不难理解,我门来看一下,C中的代码的各个变量是怎么处理的先:
_DATA segment word public 'DATA'
_bb label word
dw 1
_DATA ends
_BSS segment word public 'BSS'
_aa label word
db 2 dup (?)
_BSS ends
?debug C E9
_DATA segment word public 'DATA'
s@ label byte
db 99
db 61
db 37
db 100
db 0
_DATA ends
可以看到BB 和"C=%D"被汇编成初始化数据段.AA处理成为初始化数据段BSS
在同一模块中所以"C=%D"为BB的继续,即使不在同一模块,但他们的段名,和类别相同,他们也会根据对齐类型,和组合类型组合在一起,
而函数中的X,Y A,B则是在栈中实现
因为以SMALL格式 所以
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP,ss:DGROUP
所有数据都能在同一段中进行访问!
不要忘记
_TEXT segment byte public 'CODE'
extrn _printf:near
_TEXT ends
public _main
public _sum
public _bb
public _aa
end
即使在同一模块,但因为他们是全局函数,所以同样要声明.PRINTF则说明定义在另一模块中.
代码中没有看到堆栈段,就用系统分配的,如果有,要是以SMALL模式一样会在DGROUP中出现.
所以代码中引用变量默认的DS SS都以指向DGROUP.
至于函数的代码,主要是对栈的操作.大家自己看一看
而在汇编中,段的简化定义在SMALL模式下就生成上边的相应的段的定义,如果你要自己定义完整的段定义,那段名和对齐类型,组合类型,类别,都要你自己指出,这样也能调整段的位置,
如果自己定义要明白在同一模块中同一段名(类别缺省或相同)后边的为前边同名段的继续,若不同名则根据对齐类型衔接,
若不在同模块下,同名的段(类别缺省或相同)根据组合类型决定,若为PUBILC则根据对齐类型放在上一个同名段的后边!
SMALL存储模式就是帮你做了这些工作.为了使各个段在一起对段名和对齐类型,组合类型,类别,做了处理,把不同类型的数据分为不同的段名,不同模块的同段名的段根据对齐类型,组合类型组织在一起,组合后的各个"大"段根据对齐类型在组织在一起,在通过段组来实现所有数据段或代码段在同一段内!
#include "stdio.h"
sum(int x,int y)
...{
return x+y;
}
int aa;
int bb=1;
main()
...{
int a=1;
int b=2;
int c=sum(a,b);
printf("c=%d",c);
}
好,我们知道汇编里函数内的变量是自动变量,也就是通过栈来实现的,很容易忽略的就是MAIN函数也是函数,代码中的A,B变量也是自动变量.先生成汇编代码TCC -S 文件
ifndef ??version
?debug macro
endm
endif
?debug S "shiyan.c"
_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP,ss:DGROUP
_TEXT ends
_DATA segment word public 'DATA'
d@ label byte
[email=d@w]d@w[/email] label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
[email=b@w]b@w[/email] label word
?debug C E9A77AA4360873686979616E2E63
?debug C E957A7972615433A5C54435C494E434C5544455C737464696F2E68
?debug C E957A7972616433A5C54435C494E434C5544455C7374646172672E+
?debug C 68
_BSS ends
_TEXT segment byte public 'CODE'
; ?debug L 2
_sum proc near
push bp
mov bp,sp
; ?debug L 4
mov ax,word ptr [bp+4]
add ax,word ptr [bp+6]
jmp short @1
@1:
; ?debug L 5
pop bp
ret
_sum endp
_TEXT ends
_DATA segment word public 'DATA'
_bb label word
dw 1
_DATA ends
_TEXT segment byte public 'CODE'
; ?debug L 8
_main proc near
push bp
mov bp,sp
sub sp,2
push si
push di
; ?debug L 10
mov si,1
; ?debug L 11
mov di,2
; ?debug L 12
push di
push si
call near ptr _sum
pop cx
pop cx
mov word ptr [bp-2],ax
; ?debug L 13
push word ptr [bp-2]
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
pop cx
@2:
; ?debug L 14
pop di
pop si
mov sp,bp
pop bp
ret
_main endp
_TEXT ends
_BSS segment word public 'BSS'
_aa label word
db 2 dup (?)
_BSS ends
?debug C E9
_DATA segment word public 'DATA'
s@ label byte
db 99
db 61
db 37
db 100
db 0
_DATA ends
_TEXT segment byte public 'CODE'
extrn _printf:near
_TEXT ends
public _main
public _sum
public _bb
public _aa
end
代码比起C的代码要多很多,但不难理解,我门来看一下,C中的代码的各个变量是怎么处理的先:
_DATA segment word public 'DATA'
_bb label word
dw 1
_DATA ends
_BSS segment word public 'BSS'
_aa label word
db 2 dup (?)
_BSS ends
?debug C E9
_DATA segment word public 'DATA'
s@ label byte
db 99
db 61
db 37
db 100
db 0
_DATA ends
可以看到BB 和"C=%D"被汇编成初始化数据段.AA处理成为初始化数据段BSS
在同一模块中所以"C=%D"为BB的继续,即使不在同一模块,但他们的段名,和类别相同,他们也会根据对齐类型,和组合类型组合在一起,
而函数中的X,Y A,B则是在栈中实现
因为以SMALL格式 所以
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP,ss:DGROUP
所有数据都能在同一段中进行访问!
不要忘记
_TEXT segment byte public 'CODE'
extrn _printf:near
_TEXT ends
public _main
public _sum
public _bb
public _aa
end
即使在同一模块,但因为他们是全局函数,所以同样要声明.PRINTF则说明定义在另一模块中.
代码中没有看到堆栈段,就用系统分配的,如果有,要是以SMALL模式一样会在DGROUP中出现.
所以代码中引用变量默认的DS SS都以指向DGROUP.
至于函数的代码,主要是对栈的操作.大家自己看一看
而在汇编中,段的简化定义在SMALL模式下就生成上边的相应的段的定义,如果你要自己定义完整的段定义,那段名和对齐类型,组合类型,类别,都要你自己指出,这样也能调整段的位置,
如果自己定义要明白在同一模块中同一段名(类别缺省或相同)后边的为前边同名段的继续,若不同名则根据对齐类型衔接,
若不在同模块下,同名的段(类别缺省或相同)根据组合类型决定,若为PUBILC则根据对齐类型放在上一个同名段的后边!
SMALL存储模式就是帮你做了这些工作.为了使各个段在一起对段名和对齐类型,组合类型,类别,做了处理,把不同类型的数据分为不同的段名,不同模块的同段名的段根据对齐类型,组合类型组织在一起,组合后的各个"大"段根据对齐类型在组织在一起,在通过段组来实现所有数据段或代码段在同一段内!
相关文章推荐
- NS2 分裂机制及代码分析<一>---解释类成员变量与编译类成员变量互操作
- android源码解析之(一)-->异步消息机制
- <Oracle基本的数据存储机制-表>
- [原创]WCF技术剖析之八:ClientBase<T>中对ChannelFactory<T>的缓存机制
- quick-cocos2d-x的热更新机制实现<一>前言
- quick-cocos2d-x的热更新机制实现<四>update包(lua)(中)
- vb反编译器.rar > modAsm.bas
- 写一个MyList<T>的类,内部用T[]实现(不能使用系统的List<T>类),需要实现的接口如下:
- 数据存储详解(二)---->File存储:内部存储 -Cache和外部存储-SD卡
- [LINQ] 深入SQL Entity与EntityRef<T>内部
- ASM+RAC==>>单实例+文件系统迁移步骤
- org.objectweb.asm.ClassWriter.<init>(I)V和org.objectweb.asm.ClassWriter.<init>(Z)V
- storm消息确认机制<转>
- 使用<a>标签提交action会执行两次后台方法的原因(反射机制小实例问题的解决)
- cin>>和cin.get()对EOF的处理机制有什么不同
- quick-cocos2d-x的热更新机制实现<四>update包(lua)(下)
- Android事件分发机制------------>验证+理解
- Handler消息机制------->理解
- vector<bool>中的代理机制与程序运行效率
- java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z