那里有没有开源的实时操作系统?我听说过实时Linux,但大多数实现似乎都是一个专有的RTOS(你需要付费),它将Linux作为一个过程运行 - 就像Ardence的RTX实时系统适用于Windows一样.
编辑:我应该澄清一点,我正在寻找RTOS来使用多核x86系列CPU.
我已经通过在C中编写语句,用"gcc -S"编译它们并研究输出,一直在教自己GNU Assembly一段时间.这在x86(并使用-m32编译)上工作正常,但在我的AMD64框中,对于此代码(仅作为示例):
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC给了我:
.file "test.c" .text .globl main .type main, @function main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: movl $0, %eax leave ret .LFE2: .size main, .-main .section .eh_frame,"a",@progbits .Lframe1: .long .LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .byte 0x1 .string "zR" .uleb128 0x1 .sleb128 -8 .byte 0x10 .uleb128 0x1 .byte 0x3 .byte 0xc .uleb128 0x7 .uleb128 0x8 .byte 0x90 .uleb128 0x1 .align 8 .LECIE1: .LSFDE1: .long .LEFDE1-.LASFDE1 .LASFDE1: .long .LASFDE1-.Lframe1 .long .LFB2 .long …
我遇到了一个有趣的问题.我忘了我正在使用64位机器和操作系统并写了一个32位汇编代码.我不知道如何编写64位代码.
这是Linux上Gnu Assembler(AT&T语法)的x86 32位汇编代码.
//hello.S
#include <asm/unistd.h>
#include <syscall.h>
#define STDOUT 1
.data
hellostr:
.ascii "hello wolrd\n";
helloend:
.text
.globl _start
_start:
movl $(SYS_write) , %eax //ssize_t write(int fd, const void *buf, size_t count);
movl $(STDOUT) , %ebx
movl $hellostr , %ecx
movl $(helloend-hellostr) , %edx
int $0x80
movl $(SYS_exit), %eax //void _exit(int status);
xorl %ebx, %ebx
int $0x80
ret
Run Code Online (Sandbox Code Playgroud)
现在,这个代码应该在32位处理器和32位操作系统上正常运行吗?我们知道64位处理器向后兼容32位处理器.所以,这也不是问题.问题出现是因为64位操作系统和32位操作系统中的系统调用和调用机制不同.我不知道为什么但是他们改变了32位linux和64位linux之间的系统调用号码.
asm/unistd_32.h定义:
#define __NR_write 4
#define __NR_exit 1
Run Code Online (Sandbox Code Playgroud)
asm/unistd_64.h定义:
#define __NR_write 1
#define __NR_exit 60
Run Code Online (Sandbox Code Playgroud)
无论如何使用宏而不是直接数字都可以获得回报.它确保正确的系统呼叫号码.
当我组装和链接并运行程序时.
$cpp hello.S hello.s …Run Code Online (Sandbox Code Playgroud) 在执行该指令之前,fs包含0x0.
另外我想知道如何从GDB中的这个内存区读取,这个命令是什么?
该在线LLVM演示页面有一个选项生成LLVM C++ API代码从一个源代码后端.但是,该演示页面现已禁用.我想知道我们如何使用可用的LLVM工具自己完成它.
我尝试了以下内容
clang++ -c -emit-llvm input.cpp -o input.ll
llc -march=cpp -o input.ll.cpp input.ll
Run Code Online (Sandbox Code Playgroud)
这给出了以下错误
llc: error: invalid target 'cpp'.
Run Code Online (Sandbox Code Playgroud)
我使用的是LLVM/Clang 3.2版.
我在下面的x86_64非常复杂的程序上做了gcc -S:
int main() {
int x = 3;
x = 5;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
而我得到的是:
.file "main.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $3, -4(%rbp)
movl $5, -4(%rbp)
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
我想知道是否有人可以帮助我理解输出或引用我的一些链接解释.具体来说,cfi ,LFB0,LFE0 , leave意味着什么?关于这些我能找到的就是这篇文章但却无法完全理解它的用途.另外,ret在这种情况下做什么?我猜它正在回归__libc_start_main(),反过来会打电话 …
我对Delphi 10.2 Pascal编程语言中的特定编程问题有疑问.
StringOfChar和FillChar在2012年之前发布的CPU上的Win64 Release版本下无法正常工作.
FillChar的预期结果只是在给定的内存缓冲区中重复8位字符的简单序列.
StringOfChar的预期结果是相同的,但结果存储在字符串类型中.
但实际上,当我在10.2版本的Delphi中编译我们在10.2之前的Delphi中运行的应用程序时,我们为Win64编译的应用程序在2012年之前发布的CPU上停止正常工作.
StringOfChar和FillChar不能正常工作 - 它们返回一串不同的字符,虽然是重复的模式 - 而不仅仅是它们应该具有相同字符的序列.
这是足以证明问题的最小代码.请注意,序列的长度应至少为16个字符,并且字符不应为nul(#0).代码如下:
procedure TestStringOfChar;
var
a: AnsiString;
ac: AnsiChar;
begin
ac := #1;
a := StringOfChar(ac, 43);
if a <> #1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1 then
begin
raise Exception.Create('ANSI StringOfChar Failed!!');
end;
end;
Run Code Online (Sandbox Code Playgroud)
我知道StackOverflow上有很多Delphi程序员.你遇到同样的问题吗?如果是,您如何解决?解决办法是什么?顺便说一句,我已经联系了Delphi的开发人员,但到目前为止他们还没有确认也没有否认这个问题.我正在使用Embarcadero Delphi 10.2版本25.0.26309.314.
更新:
如果您的CPU是在2012年或之后生产的,则在调用StringOfChar之前还要包含以下行以重现该问题:
const
ERMSBBit = 1 shl 9; //$0200
begin
CPUIDTable[7].EBX := CPUIDTable[7].EBX and not ERMSBBit;
Run Code Online (Sandbox Code Playgroud)
至于2017年4月的RAD Studio 10.2工具链问题修补程序 - 尝试过它而没有它 - 它没有帮助.无论Hotfix如何,问题都存在.
我试图使用64位积分作为位图,并原子地获取/释放各个位的所有权.
为此,我编写了以下无锁代码:
#include <cstdint>
#include <atomic>
static constexpr std::uint64_t NO_INDEX = ~std::uint64_t(0);
class AtomicBitMap {
public:
static constexpr std::uint64_t occupied() noexcept {
return ~std::uint64_t(0);
}
std::uint64_t acquire() noexcept {
while (true) {
auto map = mData.load(std::memory_order_relaxed);
if (map == occupied()) {
return NO_INDEX;
}
std::uint64_t index = __builtin_ctzl(~map);
auto previous =
mData.fetch_or(bit(index), std::memory_order_relaxed);
if ((previous & bit(index)) == 0) {
return index;
}
}
}
private:
static constexpr std::uint64_t bit(std::uint64_t index) noexcept {
return std::uint64_t(1) << index;
}
std::atomic_uint64_t mData{ …Run Code Online (Sandbox Code Playgroud) 考虑 x64 Intel 程序集中的以下变量引用,其中变量a在.data节中声明:
mov eax, dword ptr [rip + _a]
Run Code Online (Sandbox Code Playgroud)
我很难理解这个变量引用是如何工作的。既然a是对应于变量运行时地址的符号(带重定位),如何[rip + _a]解引用正确的内存位置a?事实上,rip保存当前指令的地址,它是一个大的正整数,所以加法会导致错误的地址a?
相反,如果我使用 x86 语法(非常直观):
mov eax, dword ptr [_a]
Run Code Online (Sandbox Code Playgroud)
,我收到以下错误:64 位模式不支持 32 位绝对寻址。
有什么解释吗?
1 int a = 5;
2
3 int main() {
4 int b = a;
5 return b;
6 }
Run Code Online (Sandbox Code Playgroud)
编译gcc -S -masm=intel abs_ref.c -o abs_ref::
1 .section __TEXT,__text,regular,pure_instructions
2 .build_version macos, 10, 14
3 …Run Code Online (Sandbox Code Playgroud) int read_val();
long read_and_process(int n) {
long vals[n];
for (int i = 0; i < n; i++)
vals[i] = read_val();
return vals[n-1];
}
Run Code Online (Sandbox Code Playgroud)
x86-64 GCC 5.4编译的汇编语言代码为:
read_and_process(int):
pushq %rbp
movslq %edi, %rax
>>> leaq 22(,%rax,8), %rax
movq %rsp, %rbp
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
andq $-16, %rax
leal -1(%rdi), %r13d
subq %rax, %rsp
testl %edi, %edi
movq %rsp, %r14
jle .L3
leal -1(%rdi), %eax
movq %rsp, %rbx
leaq 8(%rsp,%rax,8), %r12
movq %rax, %r13
.L4:
call read_val()
cltq …Run Code Online (Sandbox Code Playgroud) x86-64 ×10
assembly ×7
gcc ×4
linux ×3
c++ ×2
gdb ×2
x86 ×2
c ×1
compiler-bug ×1
delphi ×1
intel-syntax ×1
llvm ×1
open-source ×1
rtos ×1
windows ×1