1. Write the C language program ch03_06_01.c
/* * The goal of this program is to count the occurrences of a specific character in a given string and print the result. * The length of a char is 1 byte, while the length of a char* is 8 bytes (refer to "Computer Systems: A Programmer's Perspective" Table 3.3 "Data Formats") * The assembly function CountChars_ passes the first parameter as 8 bytes to rsi, and the second parameter as 1 byte to sil. */#include <stdio.h>extern unsigned long long CountChars_(const char* s,char c);int main(void){ const char nl='\n'; const char* s0="Test string: "; const char* s1=" SearchChar: "; const char* s2=" Count: "; char c; const char* s; s="Four score and seven seconds ago,..."; printf("%c%s%s%c",nl,s0,s,nl); c='s'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='o'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='z'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='F'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='.'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); s="Red Green Blue Cyan Magenta Yellow"; printf("%c%s%s%c",nl,s0,s,nl); c='e'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='w'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='l'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='Q'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); c='n'; printf("%s%c%s%llu%c",s1,c,s2,CountChars_(s,c),nl); return 0;}
2. Write the assembly code ch03_06_02.asm
.text.globl CountChars_CountChars_: pushq %rsi movb %sil,%cl # First, pass the value of the second parameter c to %cl movq %rdi,%rsi # Then, pass the first parameter string s to %rsi xorq %rdx,%rdx # %rdx is used as a counter, initialize to zero xorq %r8,%r8 # Also initialize %r8 to zero loop: lodsb # This instruction loads the character pointed to by %rsi into the al register, then increments %rsi to point to the next character testb %al,%al # Check if %al is equal to 0 (the string terminator '\0'), if equal, end the loop jz end cmpb %cl,%al # Compare parameter c with %al in the string sete %r8b # The sete instruction sets r8b=1 if equal, otherwise sets r8b=0 addq %r8,%rdx jmp loop end: movq %rdx,%rax # Finally, pass the accumulated value in %rdx to the return value in %rax popq %rsi ret
3. Write the Makefile and run
ch03_06_0102: ch03_06_01.c ch03_06_02.o gcc ch03_06_01.c ch03_06_02.o -o ch03_06_0102 ch03_06_02.o: ch03_06_02.asm as ch03_06_02.asm -o ch03_06_02.o
4. The running results are as follows
Test string: Four score and seven seconds ago,... SearchChar: s Count: 4 SearchChar: o Count: 4 SearchChar: z Count: 0 SearchChar: F Count: 1 SearchChar: . Count: 3 Test string: Red Green Blue Cyan Magenta Yellow SearchChar: e Count: 6 SearchChar: w Count: 1 SearchChar: l Count: 3 SearchChar: Q Count: 0 SearchChar: n Count: 3