diff --git a/chapter1.md b/chapter1.md index f2fc20c..76131f5 100644 --- a/chapter1.md +++ b/chapter1.md @@ -57,7 +57,7 @@ RISC-V(读做“risk-five”)是一种典型的精简(Reduced Instruction 图1.1列出了RV64I(RV64G的整数指令子集)的常用基础指令。 - ![fig1_1](pictures/fig1_1.png) + fig1_1 图1.1 RV64I的常用基础指令,带下划线的粗体字母从左到右连起来构成RV64I指令。 @@ -93,13 +93,12 @@ RISC-V汇编指令的格式与8086汇编是截然不同的。以最基础的加 以上的例子中,假设A=0x0000 0000 0000 0800,rs2寄存器中的低位4字节数值为0x1234ABCD,则sw指令执行完后内存中的数值为: -`[0x0000 0000 0000 0800] = 0xCD` - -`[0x0000 0000 0000 0801] = 0xAB` - -`[0x0000 0000 0000 0802] = 0x34` - -`[0x0000 0000 0000 0803] = 0x12` +``` +[0x0000 0000 0000 0800] = 0xCD +[0x0000 0000 0000 0801] = 0xAB +[0x0000 0000 0000 0802] = 0x34 +[0x0000 0000 0000 0803] = 0x12 +``` @@ -115,15 +114,17 @@ RISC-V汇编指令的格式与8086汇编是截然不同的。以最基础的加 该语句中“asm”也可以由“__asm__”来代替。在“asm”后面有时也会加上“__volatile__”表示编译器不要对括弧内的汇编代码进行任何优化,保持指令的原样。“asm”后面括号里面的便是汇编指令。例如: -`asm(“li x17,81”); //将立即数81存入x17寄存器` - -`asm(“ecall”); //调用ecall指令(作用类似8086上的int指令)` +``` +asm(“li x17,81”); //将立即数81存入x17寄存器 +asm(“ecall”); //调用ecall指令(作用类似8086上的int指令) +``` 编译器碰到以上语句后,会将引号中的汇编语句直接翻译成对应的机器码,放到所生成的目标代码中。这两行代码的作用是调用81号软中断(即1.4节中的trap),但因为它们是相邻的汇编语句,所以可以用以下的形式书写: -`asm(“li x17,81\n\t”` - - `“ecall”);` +``` +asm(“li x17,81\n\t” + “ecall”);` +``` 也就是采用分隔符“\n\t”隔开多条汇编指令。对于编译器而言,以上两种写法是等效的。实际上GCC编译器在处理内联汇编语句时,是要把asm(…)的内容“打印”到汇编文件中,所以格式控制字符是必要的。 @@ -131,17 +132,14 @@ RISC-V汇编指令的格式与8086汇编是截然不同的。以最基础的加 扩展内联汇编使得嵌入在C语言中的代码能够带输入、输出参数,同时将被汇编代码块改变的寄存器“通知”给GCC编译器,作为后者在调度寄存器时的参考。扩展内联汇编的格式为: -`asm volatile(` - -`"statements"(汇编语句模板):` - -`output_regs(输出部分):` - -`input_regs(输入部分):` - -`clobbered_regs(破坏描述部分)` - -`) ;` +``` +asm volatile( +"statements"(汇编语句模板): +output_regs(输出部分): +input_regs(输入部分): +clobbered_regs(破坏描述部分) +) ; +``` 其中asm 表示后面的代码为内嵌汇编,也可以写作__asm__;volatile 表示不想让编译器对里面的汇编代码进行优化,也可以写作__volatile__ 。"statements"是汇编语句模板;output_regs是内联汇编的输出部分,可以理解为将要被汇编语句修改的寄存器组;input_regs是内联汇编的输入部分,即语句执行所需要的输入寄存器;clobbered_regs是破坏描述部分,代表将要被汇编语句改变(破坏)的内容。扩展内联汇编中汇编语句模版是必须要的,其它3部分则都是可选内容,以下对这些部分分别进行解释: @@ -191,57 +189,32 @@ RISC-V汇编指令的格式与8086汇编是截然不同的。以最基础的加 我们再看一个稍微大一点的例子,通过这个例子我们希望能尽量把以上的知识点串起来,加深读者对RISC-V汇编语言的理解。假设有以下C语言程序test_asm.c,其源代码如例1.1所示: ``` - `1 #include ` - - `2` - - `3 void bar()` - - `4 {` - - `5 asm volatile( "li s5, 300" );` - - `6 }` - - `7` - - `8 int foo( int foo_arg )` - - `9 {` - - `10 int x;` - - `11 asm volatile( "li s5, 500" );` - - `12 bar();` - - `13 asm volatile (` - - `14 "sd s5,%0"` - - `15 :"=m"(x)` - - `16 :` - - `17 : "memory");` - - `18 printf( "x=%d\n", x );` - - `19 return 10;` - - `20 }` - - `21` - - `22 int main()` - - `23 {` - - `24 foo( 10 );` - - `25 return 0;` - - `26 }` + 1 #include + 2 + 3 void bar() + 4 { + 5 asm volatile( "li s5, 300" ); + 6 } + 7 + 8 int foo( int foo_arg ) + 9 { + 10 int x; + 11 asm volatile( "li s5, 500" ); + 12 bar(); + 13 asm volatile ( + 14 "sd s5,%0" + 15 :"=m"(x) + 16 : + 17 : "memory"); + 18 printf( "x=%d\n", x ); + 19 return 10; + 20 } + 21 + 22 int main() + 23 { + 24 foo( 10 ); + 25 return 0; + 26 } ``` 例1.1 test_asm.c代码列表 @@ -266,89 +239,47 @@ RISC-V汇编指令的格式与8086汇编是截然不同的。以最基础的加 ``` 00000000000101a4 : - 101a4: ff010113 addi sp,sp,-16 - 101a8: 00813423 sd s0,8(sp) - 101ac: 01010413 addi s0,sp,16 - 101b0: 12c00a93 li s5,300 - 101b4: 00000013 nop - 101b8: 00813403 ld s0,8(sp) - 101bc: 01010113 addi sp,sp,16 - 101c0: 00008067 ret - 00000000000101c4 : - 101c4: fd010113 addi sp,sp,-48 - 101c8: 02113423 sd ra,40(sp) - 101cc: 02813023 sd s0,32(sp) - 101d0: 03010413 addi s0,sp,48 - 101d4: 00050793 mv a5,a0 - 101d8: fcf42e23 sw a5,-36(s0) - 101dc: 1f400a93 li s5,500 - 101e0: fc5ff0ef jal ra,101a4 - 101e4: ff543623 sd s5,-20(s0) - 101e8: fec42783 lw a5,-20(s0) - 101ec: 00078593 mv a1,a5 - 101f0: 0001c7b7 lui a5,0x1c - 101f4: f7078513 addi a0,a5,-144 # 1bf70 <__clzdi2+0x2e> - 101f8: 1e2000ef jal ra,103da - 101fc: 00a00793 li a5,10 - 10200: 00078513 mv a0,a5 - 10204: 02813083 ld ra,40(sp) - 10208: 02013403 ld s0,32(sp) - 1020c: 03010113 addi sp,sp,48 - 10210: 00008067 ret - 0000000000010214
: - 10214: ff010113 addi sp,sp,-16 - 10218: 00113423 sd ra,8(sp) - 1021c: 00813023 sd s0,0(sp) - 10220: 01010413 addi s0,sp,16 - 10224: 00a00513 li a0,10 - 10228: f9dff0ef jal ra,101c4 - 1022c: 00000793 li a5,0 - 10230: 00078513 mv a0,a5 - 10234: 00813083 ld ra,8(sp) - 10238: 00013403 ld s0,0(sp) - 1023c: 01010113 addi sp,sp,16 - 10240: 00008067 ret ```