相关疑难解决方法(0)

为什么x86-64 Linux系统调用可以使用6个寄存器?

我正在用C编写一个独立程序,它只依赖于Linux内核.

我研究了相关手册 ,得知X86-64上的Linux系统调用入口点接收通过七个寄存器的系统调用号和六个参数rax,rdi,rsi,rdx,r10,r8,和r9.

这是否意味着 每个系统调用都接受六个参数?

我研究了几个libc实现的源代码,以了解它们如何执行系统调用.有趣的是,musl包含两种不同的系统调用方法:

  1. src/internal/x86_64/syscall.s

    此汇编源文件定义了一个__syscall函数,该函数将系统调用号和正好六个参数移动到ABI中定义的寄存器.该函数的通用名称暗示它可以与任何系统调用一起使用,尽管它总是将六个参数传递给内核.

  2. arch/x86_64/syscall_arch.h

    此C头文件定义了七个单独的__syscallN函数,并N指定了它们的arity.这表明只传递系统调用所需的确切数量的参数的好处超过了拥有和维护七个几乎相同的函数的成本.

所以我自己尝试了一下:

long
system_call(long number,
            long _1, long _2, long _3, long _4, long _5, long _6)
{
    long value;

    register long r10 __asm__ ("r10") = _4;
    register long r8  __asm__ ("r8")  = _5;
    register long …
Run Code Online (Sandbox Code Playgroud)

operating-system x86-64 system-calls abi linux-kernel

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

如何在ubuntu下使用nasm(程序集)从键盘读取单个字符输入?

我在ubuntu下使用nasm.顺便说一下,我需要从用户的键盘上获取单个输入字符(比如一个程序要求你输入y/n?)所以当按下键并且没有按下输入时我需要读取输入的字符.我搜索了很多,但我发现的所有内容都与此行(int 21h)有关,导致"分段错误".请帮我弄清楚如何获得单个字符或如何克服这个分段错误.

ubuntu assembly character nasm

6
推荐指数
2
解决办法
8153
查看次数

如何检查汇编语言(ASM)中的"数组长度",

我刚开始学习汇编语言.在java中,如果我们有一个Array,我们总是可以使用array.length来获取它的长度.在集会中有这样的事吗?如果是的话,有人可以在这里指导我吗?

编辑:

我很抱歉,我知道程序集没有数组,我试图简化一些事情.

我的意思是,如果我有一个变量

data DB 1,2,3,5,7,8,9,10
Run Code Online (Sandbox Code Playgroud)

鉴于DB可以包含任意数量的元素,我如何检查它包含的总变量?

像java这样的东西,使用int数组来存储它

int data = {1,2,3,4,57,8,9,10};
Run Code Online (Sandbox Code Playgroud)

我们可以只使用data.length来查找元素的总量.

assembly

6
推荐指数
3
解决办法
4万
查看次数

在64位Linux上使用中断0x80

我有一个简单的64位汇编程序,用于打印'O'和'K'后跟换行符.但是,'K'永远不会打印出来.程序的目标之一是将rax寄存器的低位中的值打印为ASCII字母.该程序专门用于64位Linux,用于教育目的,因此不需要使用C风格的系统调用.

我怀疑这个问题要么mov QWORD [rsp], rax或是mov rcx, rsp.

目前,该程序仅输出"O"后跟换行符.

如何更改程序以使其使用rax中的值然后打印"K"以使完整输出为"OK",然后换行?

bits 64

section .data

o:  db "O"      ; 'O'
nl: dq 10       ; newline

section .text

;--- function main ---
global main         ; make label available to the linker
global _start       ; make label available to the linker
_start:             ; starting point of the program
main:               ; name of the function

;--- call interrupt 0x80 ---
mov rax, 4          ; function call: 4
mov rbx, 1          ; …
Run Code Online (Sandbox Code Playgroud)

linux assembly stack x86-64 system-calls

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

在Linux x86_64中,syscall和int 0x80是否相关?

我知道在Linux x64中,“ syscall”和“ int 0x80”汇编程序指令会在软件中生成中断,要求内核执行某些工作。它们具有不同的操作码(0F 05与CD 80),并且前者速度更快。
我不清楚它们之间是否存在任何关系:它们真的独立吗?(即:“ syscall”是否调用“ int 0x80”?)谢谢。

linux system-calls

6
推荐指数
2
解决办法
868
查看次数

“分段错误”,x86_64 汇编,AT&T 语法

我在 64 位 Linux 环境中运行我的代码,其中 Linux 内核是使用IA32_EMULATIONX86_X32 disabled构建的。

在《从头开始编程》一书中第一个程序除了产生段错误之外什么都不做:

.section .data

.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx

int $0x80
Run Code Online (Sandbox Code Playgroud)

我将代码转换为使用 x86-64 指令,但它也会出现段错误:

.section .data

.section .text
.globl _start
_start:
movq $1, %rax
movq $0, %rbx

int $0x80
Run Code Online (Sandbox Code Playgroud)

我像这样组装了这两个程序:

as exit.s -o exit.o
ld exit.o -o exit
Run Code Online (Sandbox Code Playgroud)

运行./exit给出了Segmentation fault两个。我究竟做错了什么?

PS 我看过很多用gcc组装代码的教程,但是我想使用gas

更新

结合评论和答案,这是代码的最终版本:

.section .data
.section .text

.globl _start
_start: …
Run Code Online (Sandbox Code Playgroud)

linux assembly x86-64 gnu-assembler system-calls

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

Syscall实现exit()

我写了一个简单的C程序,只调用exit()函数,但是strace说二进制文件实际上是调用exit_group,exit()是一个exit_group()包装器吗?这两个功能是否相同?如果是这样,为什么编译器会选择exit_group()而不是exit()?

c x86 assembly gcc system-calls

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

Linux 中的“int 80h”是什么?

我想了解我们为什么使用int 80h以及在汇编代码中调用它后会发生什么。像这儿:

int 80h
mov eax,1
int 80h
Run Code Online (Sandbox Code Playgroud)

它怎么知道我要调用系统退出,而不只是在eax中保存十进制数?

linux x86 assembly system-calls linux-kernel

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

汇编程序中的低级网络(x86兼容)

我希望在汇编程序中编写一个能够发送和接收网络数据包的可启动程序.我不想使用任何库,我想自己创建它(也可以在学习的同时学习).不幸的是,我无法找到有关与最低级别网卡通信的任何信息(发送原始套接字).我认为有必要使用OUTIN说明,虽然我找不到任何有关分配给网卡的端口的信息(或者如何找到它,如果它不总是相同的话).有人能指出我正确的方向吗?;-)

networking assembly raw-sockets

5
推荐指数
2
解决办法
4687
查看次数

Mac OS X运行时错误的64位汇编:"dyld:无可写段"和"Trace/BPT陷阱"

尝试运行以下程序集程序时:

.globl start

start:
    pushq $0x0 
    movq $0x1, %rax
    subq $0x8, %rsp
    int $0x80
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

dyld: no writable segment
Trace/BPT trap
Run Code Online (Sandbox Code Playgroud)

知道是什么原因引起的吗?32位汇编中的类似程序运行良好.

macos 64-bit assembly 32bit-64bit att

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