首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

《Programming from the Ground Up》阅读笔记:p88-p94

编程知识
2024年07月27日 13:38

《Programming from the Ground Up》学习第5天,p88-p94总结,总计7页。

一、技术总结

1.touppercase.s

#PURPOSE: This program converts an input file 
#to an output file with all letters 
#converted to uppercase.

#PROCESSING:
#(1)Open the input file
#(2)Open the output file
#(3)While we're not at the end of the input file
#  (a)read part of file into our memory buffer
#  (b)go throught each byte of memory, if the byte is a lower-case letter, convert it to uppercase
#  (c)write the memory buffer to output file

 .section .data

#######CONSTANTS#######

 #system call numbers
 .equ SYS_OPEN, 5
 .equ SYS_WRITE, 4
 .equ SYS_READ, 3
 .equ SYS_CLOSE, 6
 .equ SYS_EXIT, 1
 
 #options for open (look at
 #/usr/incude/asm/fcntl.h for
 #various values. You can combine them
 #by adding them or ORing them)
 #This is discussed at greater length
 #in "Counting Like a Computer"
 .equ O_RDONLY, 0
 .equ O_CREAT_WRONLY_TRUNC, 03101
 
 #standard file descriptors
 .equ STDIN, 0
 .equ STDOUT, 1
 .equ STDERR, 2
 
 #system call interrupt
 .equ LINUX_SYSCALL, 0X80
 
 .equ END_OF_FILE, 0 #This is the return value 
                     #of read which means we've
 					#hit the end of the file
 
 .equ NUMBER_ARGUMENTS, 2

.section .bss
 #Buffer - This is where the data is loaded into 
 #from the data file and written from 
 #into the output file. This should 
 #never exceed 16000 for various
 #reasons.
 
 .equ BUFFER_SIZE, 500
 .lcomm BUFFER_DATA, BUFFER_SIZE
 
 .section .text
 
 #STACK POSITIONS
 .equ ST_SIZE_RESERVE, 8
 .equ ST_FD_IN, -4
 .equ ST_FD_OUT, -8
 .equ ST_ARGC, 0 #Number of arguments
 .equ ST_ARGV_0, 4 #Name of program
 .equ ST_ARGV_1, 8 #Input file name
 .equ ST_ARGV_2, 12 #Output file name

 .globl _start
_start:
 ###INITIALIZE PROGRAM###
 #save the stack pointer

 mov %rsp, %rbp
 
 #Allocate space for our file descriptors
 #on the stack
 sub $ST_SIZE_RESERVE, %rsp

open_files:
open_fd_in:
 ###OPEN INPUT FILE###
 #open syscall
 mov $SYS_OPEN, %rax
 #input filename into %rbx
 mov ST_ARGV_1(%rbp), %rbx
 #read-only flag
 mov $O_RDONLY, %rcx
 #this doesn’t really matter for reading
 mov $0666, %rdx
 #call Linux
 int $LINUX_SYSCALL

store_fd_in:
 #save the given file descriptor
 mov %rax, ST_FD_IN(%rbp)
 
open_fd_out:
 ###OPEN OUTPUT FILE###
 #open the file
 mov $SYS_OPEN, %rax
 #output filename into %rbx
 mov ST_ARGV_2(%rbp), %rbx
 #flags for writing to the file
 mov $O_CREAT_WRONLY_TRUNC, %rcx
 #mode for new file (if it’s created)
 mov $0666, %rdx
 #call Linux
 int $LINUX_SYSCALL
 
store_fd_out:
 #store the file descriptor here
 mov %rax, ST_FD_OUT(%rbp)
 
 ###BEGIN MAIN LOOP###
read_loop_begin:

 ###READ IN A BLOCK FROM THE INPUT FILE###
 mov $SYS_READ, %rax
 #get the input file descriptor
 mov ST_FD_IN(%rbp), %rbx
 #the location to read into
 mov $BUFFER_DATA, %rcx
 #the size of the buffer
 mov $BUFFER_SIZE, %rdx
 #Size of buffer read is returned in %rax
 int $LINUX_SYSCALL
 
 ###EXIT IF WE’VE REACHED THE END###
 #check for end of file marker
 cmp $END_OF_FILE, %rax
 #if found or on error, go to the end
 jle end_loop

continue_read_loop:
 ###CONVERT THE BLOCK TO UPPER CASE###
 push $BUFFER_DATA #location of buffer
 push %rax #size of the buffer
 call convert_to_upper
 pop %rax #get the size back
 add $4, %rsp #restore %rsp
 
 ###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
 #size of the buffer
 mov %rax, %rdx
 mov $SYS_WRITE, %rax
 #file to use
 mov ST_FD_OUT(%rbp), %rbx
 #location of the buffer
 mov $BUFFER_DATA, %rcx
 int $LINUX_SYSCALL
 
 ###CONTINUE THE LOOP###
 jmp read_loop_begin

end_loop:
 ###CLOSE THE FILES###
 ##NOTE - we don’t need to do error checking on these, because error conditions
 #don’t signify anything special here
 mov $SYS_CLOSE, %rax
 mov ST_FD_OUT(%rbp), %rbx
 int $LINUX_SYSCALL
 mov $SYS_CLOSE, %rax
 mov ST_FD_IN(%rbp), %rbx
 int $LINUX_SYSCALL
 ###EXIT###
 mov $SYS_EXIT, %rax
 mov $0, %rbx
 int $LINUX_SYSCALL
 #PURPOSE: This function actually does the
 # conversion to upper case for a block
 #
 #INPUT:The first parameter is the location

 #of the block of memory to convert
 #The second parameter is the length of
 #that buffer
 #
 #OUTPUT: This function overwrites the current
 #buffer with the upper-casified version.
 #
 ##VARIABLES: %rax - beginning of buffer
 #%rbx - length of buffer
 #%rdi - current buffer offset
 #%cl - current byte being examined
 #(first part of %rcx)
 #


 ###CONSTANTS##
 #The lower boundary of our search
 .equ LOWERCASE_A, 'a'
 #The upper boundary of our search
 .equ LOWERCASE_Z, 'z'
 #Conversion between upper and lower case
 .equ UPPER_CONVERSION, 'A' - 'a'
 
 
 ###STACK STUFF###
 .equ ST_BUFFER_LEN, 8 #Length of buffer
 .equ ST_BUFFER, 12 #actual buffer
 
convert_to_upper:
 push %rbp
 mov %rsp, %rbp
 ###SET UP VARIABLES###
 mov ST_BUFFER(%rbp), %rax
 mov ST_BUFFER_LEN(%rbp), %rbx
 mov $0, %rdi

 #if a buffer with zero length was given
 #to us, just leave
 cmp $0, %rbx
 je end_convert_loop

convert_loop:
 #get the current byte
 movb (%rax,%rdi,1), %cl

 #go to the next byte unless it is between
 #’a’ and ’z’
 cmpb $LOWERCASE_A, %cl
 jl next_byte
 cmpb $LOWERCASE_Z, %cl
 jg next_byte

 #otherwise convert the byte to uppercase
 addb $UPPER_CONVERSION, %cl
 #and store it back
 movb %cl, (%rax,%rdi,1)

next_byte:
 inc %rdi #next byte
 cmp %rdi, %rbx #continue unless
                #we’ve reached the
                #end
				
 jne convert_loop

end_convert_loop:
 #no return value, just leave
 mov %rbp, %rsp
 pop %rbp
 ret

按照书上代码敲的,但是没有结果,也不报错,心累,先这样吧。

2.64位计算机上不同寄存器的作用

不同位数计算机上寄存器(register):

r8 = AL AH BL BH CL CH DL DH

r16 = AX BX CX DX BP SP SI DI

r32 = EAX EBX ECX EDX EBP ESP ESI EDI

r64 = RAX RBX RCX RDX RBP RSP RSI RDI R8 R9 R10 R11 R12 R13 R14 R15

个人认为,其实作者应该先把各个寄存器的作用列出来,这样读者才能知道代码里为什么使用这个寄存器,不然自己写的时候根本不知道使用哪个寄存器。寄存器的作用可以搜索《System V Application Binary Interface AMD64 Architecture Processor Supplement》手册(如:https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf),手册里面“Figure 3.4: Register Usage”有介绍。这里把它列出来,方便查看:

Register Usage callee saved
%rax temporary register; with variable arguments passes information
about the number of vector registers used; 1st return register
No
%rbx callee-saved register Yes
%rcx used to pass 4th integer argument to functions No
%rdx used to pass 3rd argument to functions; 2nd return register No
%rsp stack pointer Yes
%rbp callee-saved register; optionally used as frame pointer Yes
%rsi used to pass 2nd argument to functions No
%rdi used to pass 1st argument to functions No
%r8 used to pass 5th argument to functions No
%r9 used to pass 6th argument to functions No
%r10 temporary register, used for passing a function’s static chain
pointer
No
%r11 temporary register No
%r12-r14 callee-saved registers Yes
%r15 callee-saved register; optionally used as GOT base pointer Yes
%xmm0–%xmm1 used to pass and return floating point arguments No
%xmm2–%xmm7 used to pass floating point arguments No
%xmm8–%xmm15 temporary registers No
%tmm0–%tmm7 temporary registers No
%mm0–%mm7 temporary registers No
%k0–%k7 temporary registers No
%st0,%st1 temporary registers, used to return long double arguments No
%st2–%st7 temporary registers No
%fs thread pointer Yes
mxcsr SSE2 control and status word partial
x87 SW x87 status word No
x87 CW x87 control word Yes
tilecfig Tile control register No

二、英语总结

无。

三、其它

先追求完成,再追求完美,每天看一点。

四、参考资料

1. 编程

(1)Jonathan Bartlett,《Programming From The Ground Up》:https://book.douban.com/subject/1787855/

2. 英语

(1)Etymology Dictionary:https://www.etymonline.com

(2) Cambridge Dictionary:https://dictionary.cambridge.org

欢迎搜索及关注:编程人(a_codists)

From:https://www.cnblogs.com/codists/p/18326929
本文地址: http://shuzixingkong.net/article/480
0评论
提交 加载更多评论
其他文章 一款.NET开源、跨平台的DASH/HLS/MSS下载工具
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、跨平台的DASH/HLS/MSS下载工具,并且支持点播和直播(DASH/HLS)的内容下载:N_m3u8DL-RE。 网络流媒体传输协议介绍 DASH DASH是一种基于HTTP的自适应流媒体网络传输协议,它允许流媒体内容以多
一款.NET开源、跨平台的DASH/HLS/MSS下载工具 一款.NET开源、跨平台的DASH/HLS/MSS下载工具 一款.NET开源、跨平台的DASH/HLS/MSS下载工具
不是,大哥,咱这小门小户的,别搞我CDN流量啊
分享是最有效的学习方式。 博客:https://blog.ktdaddy.com/ 最近遇上事儿了,老猫的小小博客网站【程序员老猫的博客】被人盗刷CDN流量了。开始的时候收到了欠费的短信也没有怎么去重视。虽然说费用没有多少,但是也是一个教训。 博客从最初地搭建到现在确实也经过好几年了,天真地以为确实
不是,大哥,咱这小门小户的,别搞我CDN流量啊 不是,大哥,咱这小门小户的,别搞我CDN流量啊 不是,大哥,咱这小门小户的,别搞我CDN流量啊
业务场景---Token无感刷新
业务场景描述 假设用户正在填写一个复杂的表单,由于表单内容繁多,用户花费了很长时间才填完。这时,如果Token已经过期,系统会让用户重新登录,这种体验显然是非常糟糕的。为了避免这种情况,我们需要在Token即将过期或已经过期时,自动刷新Token,而不影响用户正在进行的操作。 技术实现思路 一、准备
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
​《FFmpeg开发实战:从零基础到短视频上线》一书的“10.2 FFmpeg推流和拉流”提到直播行业存在RTSP和RTMP两种常见的流媒体协议。除此以外,还有于2017年推出的SRT协议,相比常见的RTMP协议,SRT协议具有更低的延迟,并且消除了卡帧、抖动等花屏现象。腾讯视频云已经引入了SRT协
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
C# 通过反射(Reflection)调用不同名泛型方法
概述 由于工作需要,需要通过数据类型和方法名控制方法走向 用到的数据类型有8种(string,Int16,Int32,Int64,Boolean,Byte,Single,Double) 读取的方法(参数一致,但是数据不同的泛型方法,返回值也是泛型)暂时只有11种,但肯定的是,后续一定会增加 原本计划
超级猫超级签名分发平台前台SQL注入漏洞+前台任意文件删除漏洞+前台远程文件写入漏洞+前台任意文件读取漏洞+前台任意命令执行漏洞
超级猫超级签名分发平台前台SQL注入漏洞+前台任意文件删除漏洞+前台远程文件写入漏洞+前台任意文件读取漏洞+前台任意命令执行漏洞
超级猫超级签名分发平台前台SQL注入漏洞+前台任意文件删除漏洞+前台远程文件写入漏洞+前台任意文件读取漏洞+前台任意命令执行漏洞 超级猫超级签名分发平台前台SQL注入漏洞+前台任意文件删除漏洞+前台远程文件写入漏洞+前台任意文件读取漏洞+前台任意命令执行漏洞 超级猫超级签名分发平台前台SQL注入漏洞+前台任意文件删除漏洞+前台远程文件写入漏洞+前台任意文件读取漏洞+前台任意命令执行漏洞
ComfyUI插件:ComfyUI Impact 节点(一)
前言: 学习ComfyUI是一场持久战,而 ComfyUI Impact 是一个庞大的模块节点库,内置许多非常实用且强大的功能节点 ,例如检测器、细节强化器、预览桥、通配符、Hook、图片发送器、图片接收器等等。通过这些节点的组合运用,我们可以实现的工作有很多,例如自动人脸检测和优化修复、区域增强、
ComfyUI插件:ComfyUI Impact 节点(一) ComfyUI插件:ComfyUI Impact 节点(一) ComfyUI插件:ComfyUI Impact 节点(一)
Spring 常用的三种拦截器详解
在开发过程中,我们常常使用到拦截器来处理一些逻辑。最常用的三种拦截器分别是 AOP、 Interceptor 、 Filter,但其实很多人并不知道什么时候用AOP,什么时候用Interceptor,什么时候用Filter,也不知道其拦截顺序,内部原理。今天我们详细介绍一下这三种拦截器。
Spring 常用的三种拦截器详解 Spring 常用的三种拦截器详解