C语言引用汇编代码里的全局标号或变量
来源:互联网 发布:单片机的加密模式 编辑:程序博客网 时间:2024/04/30 11:19
在内核的include/linux/linkage.h中定义了:
#ifndef ENTRY
#define ENTRY(name) \
.globl name; \
ALIGN; \
name:
#endif
#endif /* LINKER_SCRIPT */
在arch/arm/mach-socfpga/headsmp.S 中定义了一下两个全局变量:
.arch armv7-a
ENTRY(secondary_trampoline)
movw r2, #:lower16:cpu1start_addr
movt r2, #:upper16:cpu1start_addr
/* The socfpga VT cannot handle a 0xC0000000 page offset when loading
the cpu1start_addr, we bit clear it. Tested on HW and VT. */
bic r2, r2, #0x40000000
ldr r0, [r2]
ldr r1, [r0]
bx r1
ENTRY(secondary_trampoline_end)
并在对应的头文件arch/arm/mach-socfpga/core.h中声明:
extern char secondary_trampoline, secondary_trampoline_end;
而在platsmp.c中如何应用这个全局变量呢?
static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; //这里获取这个两个变量的地址,并且根据地址得到这段代码的长度
if (cpu1start_addr) {
memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); //拷贝从secondary_trampoline标号开始的代码段地址
__raw_writel(virt_to_phys(socfpga_secondary_startup),
(sys_manager_base_addr+(cpu1start_addr & 0x000000ff)));
flush_cache_all();
smp_wmb();
outer_clean_range(0, trampoline_size);
/* This will release CPU #1 out of reset.*/
__raw_writel(0, rst_manager_base_addr + 0x10);
}
return 0;
}
而标号(变量)secondary_trampoline_end和secondary_trampoline的内容时对应的text的代码段:
root@socfpga_cyclone5:~# memtool -32 0x0045df80 6
Reading 0x6 count starting at address 0x0045DF80
0x0045DF80: E30E2F38 E3482067 E3C22101 E5920000
0x0045DF90: E5901000 E12FFF11
备注:内核空间的地址在2GB处,即0x80000000,而DDR的物理地址在0x0地址处,所以可以从System.map中得到这两个变量的虚拟地址:
8045df80 T secondary_trampoline
8045df98 T secondary_trampoline_end
转成物理地址0x8045df80 - 0x80000000=0x0045df80,并可以用objdump工具反汇编vmlinux,可以查看此虚拟地址处的汇编代码,和上面显示的是一致的。
结论:
汇编中用.global name定义的全局变量在C语言中引用的一段text代码,而该变量的地址也就是这段text代码的地址。
即汇编全局name在C语言中也是以普通C语言全局变量一样使用,要获取这个变量的地址需要用&name获取。
而汇编中:
ldr rx, name 则是读取name标号处的内容。和C语言中直接使用name变量是一致的。(注意这里是name是相对寻址)
在汇编中要想获取name处的地址,则要使用伪指令adr或ldr。
比如:
取短程地址用:
adr rx, label_name
取长程地址用:
ldr rx, = label_name
- C语言引用汇编代码里的全局标号或变量
- GUN ARM汇编中标号的引用在汇编和C语言中区别
- GUN ARM汇编中标号的引用在汇编和C语言中区别
- GUN ARM汇编中标号的引用在汇编和C语言中区别
- c语言里如何调用汇编里的变量?
- GUN ARM汇编中标号的引用在汇编和C语言中区别(monitor_flash_len = _bss_start - _armboot_start;)
- C语言 变量的跨文件引用
- c语言-指针变量的引用
- 【C语言】指针变量的引用
- C语言的反汇编代码
- C语言的反汇编代码
- 区分汇编中的变量和标号
- C语言extern引用AT&T汇编中的变量,任意转换类型
- 汇编中标号的使用
- 【C语言】局部变量、全局变量,局部静态变量,全局静态变量,extern,static的区别
- c语言反汇编代码
- 识别c语言汇编代码
- c语言臆想--全局---局部变量
- UML_Use-Case View
- va_start和va_end的使用
- DLL(1)
- JQ
- UML_class-class
- C语言引用汇编代码里的全局标号或变量
- Android算法之二分查找算法
- 传球游戏
- TTX/Fonttools windows下安装问题 配置环境
- 使用JAVA进行词频统计
- java实现文件路径的创建
- NSBundle的使用,注意mainBundle和Custom Bundle的区别
- javascript模板引擎 ICanHaz
- 图片切换 MM_swapImg