小编Bil*_*low的帖子

将非空终止字符串传递给C中的strncmp是否合法?

我有一个16字节的数组,其中包含可执行文件的段名.

char segname[16];
Run Code Online (Sandbox Code Playgroud)

如果段名长度小于16个字节,则其余部分用空字节填充.否则,没有终止空字节.

我想比较segname各种字符串,例如__text.

strncmp使用非空终止字符串调用是否合法?

这篇文章假设它是合法的.此源代码也使其合法化.但是我的男人的页面说:

strncmp()函数按字典顺序比较以null结尾的字符串s1s2.

传递给strncmp的大小将是segname.

我想知道我应该参考什么.

c standards standard-library strncmp

45
推荐指数
2
解决办法
3453
查看次数

strcmp()为相同的字符串比较返回不同的值

char s1[] = "0";
char s2[] = "9";
printf("%d\n", strcmp(s1, s2));   // Prints -9
printf("%d\n", strcmp("0", "9")); // Prints -1
Run Code Online (Sandbox Code Playgroud)

为什么strcmp在收到相同参数时会返回不同的值?

这些值仍然合法,因为strcmp的手册页说strcmp的返回值可以小于,大于或等于0,但我不明白为什么它们在这个例子中是不同的.

manpage string-comparison strcmp string.h

8
推荐指数
1
解决办法
717
查看次数

指令流水线和每条指令的循环之间的链接

我理解指令流水线的基本原理.

我还得到一些指令可能需要更长的时间来执行(每条指令的周期).

但我没有得到两者之间的联系.

我看到的所有管道图似乎都有"完美"指令,它们都具有相同的长度(周期数).

4阶段管道

但是,如果第一条指令需要5个周期,第二条指令需要3个周期呢?cpu是否会停顿2个周期?

这个摊位会被称为泡沫吗?或者这与危害和数据依赖性不同?

此外,指令的长度(以字节为单位)是否以任何方式重要?

cpu assembly executable cpu-architecture

8
推荐指数
1
解决办法
474
查看次数

没有编译器警告明显的段错误

我很惊讶这个编译没有任何警告:

int main()
{ 
    *"abc" = '\0';
}
Run Code Online (Sandbox Code Playgroud)

gcc main.c -Wall -Wextraclang main.c -Weverything.

为什么没有这个警告?有没有办法不会引起分段错误?

c gcc clang segmentation-fault gcc-warning

7
推荐指数
1
解决办法
228
查看次数

cpp和gcc -E之间的区别

我想这两个cpp foo.cgcc -E foo.c做预处理源文件相同的方式,但我得到了他们的输出为同一个文件的不同.

$ cat foo.c
#define VARIABLE 3
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y)  PASTER(x,y)
#define NAME(fun) EVALUATOR(fun, VARIABLE)

extern void NAME(mine);
Run Code Online (Sandbox Code Playgroud)

结果cpp:

$ cpp foo.c
# 1 "foo.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 329 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "foo.c" 2





extern void mine ## _ ## 3;

$
Run Code Online (Sandbox Code Playgroud)

结果gcc -Eclang -E: …

c gcc preprocessor c-preprocessor

6
推荐指数
1
解决办法
990
查看次数

bash - 以十六进制表示法输入字符到标准输入

我想非ASCII字符(写0xfe0xed等),以一个程序的标准输入。

有很多类似的问题,但我没有找到答案,因为:

  • 我想写单字节字符,而不是 unicode 字符
  • 我不能通过管道输出echo什么的

在 OS X¹ 上,您可以测试:

nm - -
Run Code Online (Sandbox Code Playgroud)

我想将目标文件魔术字节(例如0xfeedface)写入nm使用标准输入,以便我可以看到它的行为方式并且可以重新编码。

如果我使用管道,则第二个参数-(即stdin)将永远不会匹配任何字节,因为所有标准输入都将转到第一个。当使用终端而不是管道时,我可以输入Ctrl + D第一个“关闭”,第二个开始读取。

我尝试使用Ctrl + Shift + UOS X 的 Unicode 十六进制输入,但它不起作用——我无法用它写出所需的字符。

我也尝试过使用剪贴板,pbcopy但它无法读取/粘贴非 ASCII 或非 unicode 字符。

我怎样才能实现我的目标?

不要犹豫编辑,因为这是一个难以表达的问题。

¹nm在 linux 上不处理stdin

bash hex stdin character-encoding

5
推荐指数
1
解决办法
6795
查看次数

我可以从MacOS的_start代码执行`ret`指令吗?Linux呢?

我想知道ret从程序的入口点返回是否合法.

NASM示例:

section .text
global _start
_start:
ret

; Linux: nasm -f elf64 foo.asm -o foo.o && ld foo.o
; OS X:  nasm -f macho64 foo.asm -o foo.o && ld foo.o -lc -macosx_version_min 10.12.0 -e _start -o foo
Run Code Online (Sandbox Code Playgroud)

ret 从堆栈中弹出一个返回地址并跳转到它.

但是堆栈的顶部字节是程序入口点的有效返回地址,还是我必须调用exit?

此外,上面的程序不会在OS X上发生段错误.它在哪里返回?

linux macos assembly return entry-point

5
推荐指数
1
解决办法
493
查看次数

MacOS 汇编的 64 位系统调用文档

我无法找到在 MacOS 上编写 64 位程序集的良好文档。

64位 SysV ABI在 A.2.1 节中说了以下内容,并且此 SO 帖子引用了它:

  • 系统调用是通过 syscall 指令完成的。内核销毁寄存器%rcx 和%r11。

  • 从系统调用返回,寄存器 %rax 包含系统调用的结果。-4095 到 -1 之间的值表示错误,它是 -errno。

这两句话在 Linux 上没问题,但在 macOS Sierra 上却是错误的,代码如下:

global _start
extern _exit

section .text
_start:

; Align stack to 16 bytes for libc
and rsp, 0xFFFFFFFFFFFFFFF0

; Call write
mov rdx, 12             ; size
mov rsi, hello          ; buf
mov edi, 1              ; fd
mov rax, 0x2000004      ; write ; replace to mov rax, 0x1 …
Run Code Online (Sandbox Code Playgroud)

macos assembly x86-64 system-calls abi

5
推荐指数
1
解决办法
9218
查看次数

确定字符串是否是C中的有效wchar_t*

我正在尝试重新编写printf的一部分.

setlocale(LC_ALL, "en_US.UTF-8");
int ret = printf("%S\n", "??????");
printf("Printf returned %d\n", ret);
Run Code Online (Sandbox Code Playgroud)

如果格式为%s,则printf写入宽字符并返回19.

如果格式为%S,则printf返回-1,因为参数不是宽字符串(在""之前没有L).

在我自己的printf实现中,如何确定参数中传递的字符串是否宽,所以如果不是,我可以返回-1?

编辑

  • 我正在使用OS X El Capitan进行编程(但如果有可能,我会想要一个可移植的解决方案)
  • 在我的编程环境中,%S和%ls是相同的 - 这对我的问题并不重要
  • 当我没有为格式为%s的示例设置区域设置时,Printf也返回-1.这是我设置语言环境的唯一原因.
  • 我正在使用clang编译(Apple LLVM版本7.0.0(clang-700.1.76))

c string wchar-t

3
推荐指数
1
解决办法
436
查看次数

防止删除繁忙的内核模块

我有一个简单的内核模块,它创建了一个字符设备并且什么都不做。

我编写了这个测试字符设备的用户空间程序。

int main()
{
    int fd;

    fd = open("/dev/ebbchar", O_RDWR);
    if (fd < 0)
        err(1, "open");

    sleep(10);

    ret = close(fd);
    if (ret < 0)
        err(1, "close");
}
Run Code Online (Sandbox Code Playgroud)

程序在 10 秒后退出。

但是如果同时我用 rmmod 或 modprobe 删除了模块,那么 10 秒后程序段错误或挂起,并且有一个内核 oops。

如何导致 rmmod 失败,或者是否有安全删除模块的方法?

我的模块可以在其 __exit 函数中关闭文件描述符吗?

我假设崩溃是由在字符文件操作中close()间接调用release回调的函数引起的,该release函数不再存在,因为模块已被删除。

可以在此处找到内核模块的源代码(搜索清单 2)。

linux kernel kernel-module

1
推荐指数
1
解决办法
356
查看次数