惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
P
Privacy International News Feed
S
Schneier on Security
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
aimingoo的专栏
aimingoo的专栏
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
Help Net Security
Help Net Security
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Archives - TechRepublic
Security Archives - TechRepublic
云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
雷峰网
雷峰网
博客园 - 司徒正美
V
V2EX
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
N
News | PayPal Newsroom
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
Google DeepMind News
Google DeepMind News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
U
Unit 42
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
博客园 - Franky
I
InfoQ
D
DataBreaches.Net
爱范儿
爱范儿
Y
Y Combinator Blog
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

Whexy Blog

We lost the AIxCC. So, what now? Arm VMM with Apple's Hypervisor Framework Driving WaveShare E‐Paper Display with a Raspberry Pi Pico in MicroPython Use cgroup v2 inside docker containers Annual Hit Piece: Fuzzing Top Conference Paper Debunking Report Solving SSH Key Login Issues on Synology NAS Can SSD Cache Improve Synology NAS Write Speeds? Virtualization is all you need Running Windows Games on Mac Without Virtual Machines Tears of the Kingdom: End of an Era Anonymous CDN Traffic Relay Self-host Relay Service with CDN Home Networking Solution Building Your Own Blog System Connecting Smart Devices to SUSTech Campus Network Function Color Theory Stop Forkin' Around: Faster Creating of Large Processes on Linux PMU Interrupts: How to handle them Asynchronous Mutex Using QEMU to run Linux images on M1 Macbook Alligator In Vest - My first research work Experience Using Several Plugins in Complex LaTeX Projects Variance in Rust Understanding Rust Generic Traits SUSTeam: Ultimate Gaming Platform React Learning Notes Building a School Bus Schedule App for Apple Watch 12307 Train Ticket Purchase Platform Sakai and Local Folder Synchronization Building a Super Simple OpenJudge in Two Nights Setting Up Remote Backup for macOS Shell Script for Automatically Logging into SUSTech Campus Network Building a Movie Streaming System in the Dorm
Inline Assembly Language in C
Whexy · 2020-11-14 · via Whexy Blog

Whexy /

November 14, 2020

Writing assembly code is hard and boring! However, if you want to set regisiters, read memories, sometimes you must do the "dirty work".

Luckily we have GCC's help. GCC provides a keyword asm, which allows you to embed assembler instructions within C code. C language definitely saves our life.

A basic asm statement has the following syntax:

asm asm-qualifiers ( Assembler Instructions );

For example, in PMU settings , we want to read the system register PMCR_EL0, to make sure whether the PMU is set up successfully. The corresponding assembler instruction is MRS x0, PMCR_EL0. In the C code, we can write:

asm ("mrs x0, PMCR_EL0");

Notice that the asm-qualifiers are omitted. All basic asm blocks are implicitly "volatile".

You should be warned that GCC doesn't parse the assembler instructions and have no idea about what they mean or even whether they are valid or not.

Basic asm knows nothing about the C syntax around. For example, if you want to put a integer stored in C variable int_a into a register, you cannot use basic asm.

With extended asm you can read and write C variables from assembler and perform jumps from assembler codes to C labels. The extended asm has the following syntax:

asm qualifiers (AssemblerTemplate
                 : output_constraint (C lvalue)
                 : input_constraint (C expression)
                 : Clobbers)

Some assembler instructions will have side-effect, and we should explicitly use qualifier volatile to tell GCC don't optimize our code (yes, GCC is really smart and sometimes we need to tell it try not be so smart).

Constraints

Constraint is kind of confusing. We only need to know one common constraint we are likely to use when configuring Ninja.

The constraint is r marks the related calculation result can be stored in a general register, often used in input constraint. On the other hand, =r means the same thing, with write-only register, often used in output constraint.

For example, the following code change the value in system register.

asm volatile("msr pmintenset_el1, %0" : : "r" ((u64)(0 << 31)));

It marks the C expression (u64) (0<<31) to be stored in any general register. While running, GCC will assign a general register to fill the %0 in the assembler template, and fill it with the calculation result of the expression.

Another example of print the value stored in system register.

long long f;
asm("mrs %0, PMCR_EL0" : "=r" (f));
printk(KERN_INFO "PMCR_EL0 = %llu\n", f);

It marks the C variable (long long) f to be handled as any general register. While running, GCC will assign a general register to fill the %0 in the assembler template, and bind it with variable f.

Clobber List

Extended asm is designed to have a C expression as input and have a C left value written with the output. But sometimes our assembler code have side effects, like we will change the stored value in another register.

Unfortunately, GCC don't know the effect, since it cannot understand assembler instuctions (still remember GCC is designed to understand C code?). So we must explicitly list the registers that is affected, that's why we have clobber list.

Here's an example

asm( "movl %0,%%eax;\n\tmovl %1,%%ecx;\n\tcall _foo"
        : /*no outputs*/
        : "g" (from), "g" (to)
        : "eax", "ecx"
    );

That is an x86 example, and feel no worry that you cannot understand because so am I. The only thing we care is that we mark eax and ecx as clobber, so GCC won't depend on these two register to maintain other things.

© LICENSED UNDER CC BY-NC-SA 4.0