- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是汇编语言的新手,我必须实现 read使用汇编语言的函数x64
在 MAC
.
到目前为止,这就是我所做的:
;;;;;;ft_read.s;;;;;;
global _ft_read:
section .text
extern ___error
_ft_read:
mov rax, 0x2000003 ; store syscall value of read on rax
syscall ; call read and pass to it rdi , rsi, rdx ==> rax read(rdi, rsi, rdx)
cmp rax, 103 ; compare rax with 103 by subtracting 103 from rax ==> rax - 103
jl _ft_read_error ; if the result of cmp is less than 0 then jump to _ft_read_error
ret ; else return the rax value which is btw the return value of syscall
_ft_read_error:
push rax
call ___error
pop rcx
mov [rax], rcx
mov rax, -1
ret
正如你在上面看到的,我用 syscall 调用 read,然后我将存储在 rax 中的 read syscall 的返回值与
103
进行比较,我将解释为什么我将它与
103
进行比较但在此之前,让我解释一下其他内容,即
errno (mac 的手册页),这是关于
errno
的手册页中所写的内容:
When a system call detects an error, it returns an integer value indicat-ing indicatinging failure (usually -1) and sets the variable errno accordingly. <Thisallows interpretation of the failure on receiving a -1 and to take actionaccordingly.> Successful calls never set errno; once set, it remainsuntil another error occurs. It should only be examined after an error.Note that a number of system calls overload the meanings of these errornumbers, and that the meanings must be interpreted according to the typeand circumstances of the call.
The following is a complete list of the errors and their names as givenin <sys/errno.h>.
0
Error 0. Not used.
1
EPERM Operation not permitted. An attempt was made to perform an operation limited to processes with appropriate privileges or to theowner of a file or other resources.
2
ENOENT No such file or directory. A component of a specified pathname did not exist, or the pathname was an empty string...................................................I'll skip this part (I wrote this line btw)..................................................
101
ETIME STREAM ioctl() timeout. This error is reserved for future use.
102
EOPNOTSUPP Operation not supported on socket. The attempted operation is not supported for the type of socket referenced; for example, trying to accept a connection on a datagram socket.
lldb
调试了很多时间之后,我注意到
syscall
返回
errno
中显示的数字之一手册页,例如当我在我的
ft_read
中传递一个错误的文件描述符时使用下面的函数
main.c
像这样的代码:
int bad_file_des = -1337;// a file descriptor which it doesn't exist of course, you can change it with -42 as you like
ft_read(bad_file_des, buff, 300);
我们的
syscall
返回
9
存储在
rax
所以我比较
rax
< 103(因为 errno 值是从 0 到 102)然后跳转到
ft_read_error
因为那是它应该做的。
ft_read
时,出现了一个不知从何而来的问题。功能如下图
main.c
, 我们的阅读
syscall
返回
"the number of bytes read is returned"
, 这就是
read
系统调用按照手册中的说明返回:
On success, the number of bytes read is returned (zero indicates endof file), and the file position is advanced by this number. It isnot an error if this number is smaller than the number of bytesrequested; this may happen for example because fewer bytes areactually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), orbecause read() was interrupted by a signal. See also NOTES.
On error, -1 is returned, and errno is set appropriately. In thiscase, it is left unspecified whether the file position (if any)changes.
ft_read
function 一个好的文件描述符,一个存储数据的缓冲区,以及 50 个字节来读取,所以
syscall
将返回
50
存储在
rax
中的,然后比较就可以了>>
rax = 50
< 103 则跳转到
ft_read_error
即使没有错误,只是因为
50
是其中之一
errno
在这种情况下不是错误编号。
jc
(如果设置了进位标志则跳转)而不是
jl
(如果少则跳转)如下代码所示:
;;;;;;ft_read.s;;;;;;
global _ft_read:
section .text
extern ___error
_ft_read:
mov rax, 0x2000003 ; store syscall value of read on rax
syscall ; call read and pass to it rdi , rsi, rdx ==> rax read(rdi, rsi, rdx)
; deleted the cmp
jc _ft_read_error ; if carry flag is set then jump to _ft_read_error
ret ; else return the rax value which is btw the return value of syscall
_ft_read_error:
push rax
call ___error
pop rcx
mov [rax], rcx
mov rax, -1
ret
你猜怎么着,它工作得很好,
errno
返回
0
使用我的
ft_read
没有错误时,返回相应的错误号。
carry flag
设置好了,当没有
cmp
, 系统调用是否设置了
carry flag
当通话过程中出现错误,或者后台发生其他事情时?我想详细解释一下系统调用和
carry flag
之间的关系。 ,我还是组装新手,我非常想学习它,在此先感谢。
syscall
之间的关系是什么?和 carry flag
以及如何syscall
套吗?
main.c
我用来编译上面的汇编代码的函数:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
ssize_t ft_read(int fildes, void *buf, size_t nbyte);
int main()
{
/*-----------------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////
/********************************ft_read**********************************/
int fd = open("./main.c", O_RDONLY);
char *buff = calloc(sizeof(char), 50 + 1);
int ret = ft_read(fd, buff, 50);
printf("ret value = %d, error value = %d : %s\n", ret, errno, strerror(errno));
//don't forget to free ur buffer bro, this is just a test main don't be like me.
return (0);
}
最佳答案
部分混淆是术语“系统调用”用于两个真正不同的东西:
syscall
调用。操作说明。read()
,由用户空间 C 库提供,作为 C 程序方便地访问 #1 的功能的一种方式。-1
来指示错误的约定。从函数和设置变量
errno
.但是,这不是#1 指示错误的便捷方式。
errno
是位于程序内存某处的全局(或线程局部)变量;内核不知道在哪里,告诉它会很尴尬,所以内核不能轻易地直接写这个变量。内核以其他方式返回错误代码更简单,并将其留给 C 库设置
errno
多变的。
rax
包含系统调用的返回值(这里是读取的字节数);如果确实发生了错误,
eax
包含错误代码(它通常是 32 位值,因为
errno
是
int
)。因此,如果您在汇编中编写,那是您应该期望看到的。
sysret
将控制权转移回用户空间的指令。该指令的功能之一是恢复
rflags
从
r11
注册.内核将保存您进程的原始
rflags
当系统调用开始时,它只需要在加载到
r11
之前或之后设置或清除这个 64 位值中的低位(即进位标志所在的位置)。为
sysret
做准备.然后,当您的进程继续执行
syscall
之后的指令时,进位标志将处于相应的状态。
cmp
指令当然是 x86 CPU 设置进位标志的方法之一,但绝不是唯一的方法。即使是这样,您在用户空间程序中看不到该代码也不应该感到惊讶,因为它是内核决定了它的设置方式。
read()
函数需要在内核约定 (#1) 和 C 程序员所期望的 (#2) 之间进行接口(interface),因此他们必须编写一些代码来检查进位标志并填充
errno
如果需要的话。他们的这个函数的代码可能如下所示:
global read
read:
mov rax, 0x2000003
; fd, buf, count are in rdi, rsi, rdx respectively
syscall
jc read_error
; no error, return value is in rax which is where the C caller expects it
ret
read_error:
; error occurred, eax contains error code
mov [errno], eax
; C caller expects return value of -1
mov rax, -1
ret
64-bit syscall documentation for MacOS assembly 上还有更多信息.我希望我可以引用一些更权威的文档,但我不知道在哪里可以找到它。这里的东西似乎是“常识”。
关于c - (进位标志)和汇编中的系统调用(Mac Os 上的 x64 Intel 语法)之间有什么关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64820365/
我有两个维度 DimFlag 和 DimPNL 以及一个事实表 FactAmount 。我正在寻找:当 pnl 是 stat(Is Stat=1) 时:sum (Actual x FlagId)对于
我试图弄清楚登录模块标志在 JAAS 中是如何工作的(使用 JBoss 5.1 EAP),我遇到了一个令人费解的情况,我希望有人能为我澄清一下。 对于背景,我的 login-config.xml 如下
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我正在通过 gradle 使用 doclet 运行 javadoc,当我运行 javadoc/doclet 任务时,我收到下一个错误: error - invalid flag: -doctitle
我尝试使用sqoop --where标志将特定的行从MySQL表导入到HDFS,但是结果不符合预期。 命令: sqoop import \ --connect "jdbc:mysql://XXXX
我有一个语言面板,其中有一个图像 (main-image),显示页面加载时的情况。我还有三个额外的图像,它们在页面加载时隐藏。 问题是当点击附加图像之一时如何切换主图像。我需要使用单击的 image
奇怪...在 StackOverflow 上有很多关于此 attr 的问题,但没有人回答我的以下问题: 我有一个span(仅作为示例),其中启用了ContentEditable。我只想保存更改的元素(
我正在使用 ChartJS 2.0 在 UI 上绘制图表。而且我能够呈现饼图。但我希望鼠标悬停时显示数据以及“%”符号。我如何追加 % 因此,如果在鼠标悬停时我得到 Rented: 93 我想看到 R
我使用的是 Servlet 3.0,我想用 HttpOnly 标志保护我的 cookie。我的 web.xml 是 true
我有一个简单的服务: public class TestService extends Service { final String LOG_TAG = "myLogs"; public void o
我正在尝试将 wget 与包含“#”符号的 url 一起使用。无论我做什么来逃避这个角色,它都不起作用。我用过\、' 和 "。但它们都不起作用。有人有什么建议吗? 谢谢! 最佳答案 如果您真的想让它有
我正在尝试创建一个数据库,但我不知道如何转义数据库名称中的 - 符号。 mysql> create database happy-face; 给我一个错误 mysql> create databa
我为我的计算机科学类(class)编写了一个程序,它读取一个文件并导入数据,然后只添加数字,但它似乎添加了一个额外的加号。 import java.io.*; //necessary for File
可能是个愚蠢的问题,但我怎样才能在与某些文本看到图像相同的行中获取图像(在本例中为标志)? 到目前为止我的 HTML 代码: FRA 最佳答案 试试这个: img { height:20px
我需要一些有关 clone() 系统调用的帮助。我试图将它与标志 CLONE_CHILD_CLEARTID 一起使用,但我看不到我指定为参数的字段值有任何变化。这是一个简单的代码: int the_c
查看 mySQL 转储时,我遇到了一些东西,想知道它们是什么。 我明白了: /*!50001 DROP TABLE IF EXISTS `xxx` */; flag 50001是什么意思,有什么意思的
是否可以传递任何 Java 编译器标志来告诉编译器不允许使用原始类型?也就是说,对于任何泛型类,让编译器强制使用参数化版本,否则抛出编译错误? 最佳答案 JDK7 (b38) 介绍 -Xlint:ra
[Flags] public enum MyEnum { None = 0, Setting1 = (1 GetAllEnums() where T : struct
我正在浏览 PackageManager API。我发现定义了以下常量: 1) GET_DISABLED_COMPONENTS 2) GET_DISABLED_UNTIL_USED_COMPONENT
我编写了一个 Go 程序来模拟按键操作。为此,我必须使用 cgo 和不同的 C 代码片段,具体取决于正在编译 Go 代码的操作系统。我编写的代码如下所示: package keyboard /* #i
我是一名优秀的程序员,十分优秀!