相关疑难解决方法(0)

程序集子程序被调用两次,甚至没有从main调用

我正在尝试定义一些在其中调用printf的子例程.一个非常简单的例子如下:

extern printf
LINUX        equ     80H
EXIT         equ     60

section .data
    intfmt: db "%ld", 10, 0

segment .text
    global  main

main:
    call os_return      ; return to operating system

os_return:
    mov  rax, EXIT      ; Linux system call 60 i.e. exit ()
    mov  rdi, 0     ; Error code 0 i.e. no errors
    int  LINUX      ; Interrupt Linux kernel

test:
    push rdi
    push rsi
    mov rsi, 10
    mov rdi, intfmt
    xor rax, rax
    call printf
    pop rdi
    pop rsi
    ret
Run Code Online (Sandbox Code Playgroud)

这里测试只是调用printf,将数字10输出到屏幕.我不希望这个被调用,因为我没有打电话给它.

但是在编译和运行时:

nasm …
Run Code Online (Sandbox Code Playgroud)

linux assembly gcc x86-64 subroutine

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

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
查看次数

GCC错误消息"错误:不支持'mov'"是什么意思?

我只是想编译一些我从书中输入的简单示例代码,GCC给出了上述错误.这是我的代码:

$ cat -n test.cpp

 1  #define READ_COMMAND    3
 2  
 3  #define MSG_LENGTH  128
 4  
 5  #include <stdlib.h>
 6  #include <stdio.h>
 7  
 8  int main(int argc, char *arg[])
 9  {
10      int syslog_command = READ_COMMAND;
11      int bytes_to_read = MSG_LENGTH;
12      int retval;
13      char buffer[MSG_LENGTH];
14  
15      asm volatile(
16          "movl %1, %%ebx\n\t"
17          "movl %2, %%ecx\n\t"
18          "movl %3, %%edx\n\t"
19          "movl $103, %%eax\n\t"
20          "int $128\n\t"
21          "movl %%eax, %0"
22          :"=r" (retval)
23          :"m"(syslog_command),"r"(buffer),"m"(bytes_to_read)
24          :"%eax","%ebx","%ecx","%edx"); …
Run Code Online (Sandbox Code Playgroud)

linux assembly gcc kernel syslog

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

Linux x86_64 汇编套接字编程

大家好。

所以我正在学习汇编。
按照我通常学习的任何新语言的学习步骤,我已经到达了使用程序集的网络。

遗憾的是,情况不太好,因为我在第 0 步几乎失败了,这将获得一个可以开始通信的套接字。

汇编代码应大致等于以下 C 代码:

#include <stdio.h>
#include <sys/socket.h>

int main(){
        int sock;
        sock = socket(AF_INET, SOCK_STREAM, 0);
}
Run Code Online (Sandbox Code Playgroud)

(让我们忽略它现在没有关闭套接字的事实。)

所以这是我到目前为止所做的:

  • 检查了手册。这意味着我需要做一个socketcall()这一切都很好。问题开始于它需要一个int描述它应该进行什么样的套接字调用的。调用手册对此也没有多大帮助,因为它仅描述了以下内容:

在某些架构上——例如 x86-64 和 ARM——没有 socketcall() 系统调用;相反,socket(2)、accept(2)、bind(2) 等实际上是作为单独的系统调用实现的。

  • 然而,在系统调用的原始列表中没有这样的调用——据我所知socket()accept()bind()listen()、 等是来自libnet而不是来自内核的调用。这让我很困惑,所以我决定编译上面的C代码并使用strace. 这产生了以下结果:

    套接字(PF_INET,SOCK_STREAM,IPPROTO_IP)= 3

  • 虽然这并没有让我更接近于知道它是什么socket() 但它确实解释了它的论点。对于女巫,我似乎没有找到合适的文档(再次)。我认为PF_INETSOCK_STREAMIPPROTO_IP就在被定义<sys/socket.h>,但我grep似乎对他们-ing没有发现使用的东西。所以我决定通过gdbdisass main查找值一起使用来实现它。这给出了以下输出:

    汇编代码转储功能主要:0x00000000004004fd …

c sockets linux assembly x86-64

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

来自GCC内联汇编的系统调用

是否可以使用内联汇编块中的系统调用来编写单个字符?如果是这样,怎么样?它应该看起来像这样的"东西":

__asm__ __volatile__
                    (
                     " movl $1,  %%edx \n\t"
                     " movl $80, %%ecx \n\t"
                     " movl $0,  %%ebx \n\t"
                     " movl $4,  %%eax \n\t"
                     " int $0x80       \n\t"
                     ::: "%eax", "%ebx", "%ecx", "%edx"
                    );
Run Code Online (Sandbox Code Playgroud)

80美元是ascii中的'P',但是没有返回任何内容.

任何建议非常感谢!

c linux gcc system-calls inline-assembly

4
推荐指数
2
解决办法
3671
查看次数

x86_64 Linux系统调用参数

我正在Linux上学习x86_64程序集,我遇到了一些我希望可以解决的冲突信息.一方面,我已经读过,对于syscall参数,你会按照rdi,rsi,rdx等顺序使用寄存器.但另一方面,我读过你使用寄存器rbx,rcx,rdx等.一个人告诉我,这是因为ABI的原因,但我并不完全明白这究竟意味着什么.

所以我想我要问的是,为什么这两种格式和哪种格式适合使用?

谢谢!

x86-64 system-calls

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

汇编中系统调用的返回值是多少?

当我尝试研究内核的系统调用的返回值时,我找到了描述它们的表,以及我需要将它放在不同的寄存器中以使它们工作.但是,我没有找到任何文档说明我从系统调用获得的返回值是什么.我只是在不同的地方找到我收到的东西将在EAX寄存器中.


TutorialsPoint:

结果通常在EAX寄存器中返回.

汇编语言循序渐进: Jeff Duntemann 编写的Linux书籍在他的程序中多次说明:

  • 查看sys_read在EAX中的返回值

  • 复制sys_read返回值以便安全保存


我没有解释任何有关此返回值的网站.有没有互联网资源?或者有人能解释我这个价值观吗?

linux assembly return-value nasm system-calls

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

地址规范形式和指针算术

在符合AMD64标准的体系结构中,地址需要在取消引用之前采用规范形式.

英特尔手册的3.3.7.1节:

在64位模式中,如果微架构的地址位63到最重要的实现位被设置为全1或全零,则认为地址是规范形式.

现在,当前操作系统和体系结构中最有意义的实现位是第47位.这给我们留下了48位的地址空间.

特别是当启用ASLR时,用户程序可能会收到第47位设置的地址.

如果使用指针标记等优化并且高位用于存储信息,则程序必须确保将第48位至第63位设置回取消引用地址之前的第47位.

但请考虑以下代码:

int main()
{
    int* intArray = new int[100];

    int* it = intArray;

    // Fill the array with any value.
    for (int i = 0; i < 100; i++)
    {
        *it = 20;
        it++;   
    }

    delete [] intArray;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在考虑的intArray是,说:

0000 0000 0000 0000 0 111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100

设置itintArray并增加it一次,并考虑sizeof(int) == …

x86-64 pointer-arithmetic access-violation aslr

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

在Windows上的Ubuntu上的Bash上汇编编译可执行文件不会产生输出

我一直在寻找汇编教程,我正在尝试运行一个hello world程序.我在Windows上使用Ubuntu上的Bash.

这是集会:

section .text
    global _start     ;must be declared for linker (ld)

_start:             ;tells linker entry point
    mov edx,len     ;message length
    mov ecx,msg     ;message to write
    mov ebx,1       ;file descriptor (stdout)
    mov eax,4       ;system call number (sys_write)
    int 0x80        ;call kernel

    mov eax,1       ;system call number (sys_exit)
    int 0x80        ;call kernel

section .data
    msg db 'Hello, world!', 0xa  ;string to be printed
    len equ $ - msg     ;length of the string
Run Code Online (Sandbox Code Playgroud)

我正在使用这些命令来创建可执行文件:

nasm -f elf64 hello.asm -o hello.o
ld …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly nasm windows-subsystem-for-linux

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

是否可以在64位Linux中使用相同的可执行文件中的64位和32位指令?

64位CPU(amd64)在兼容模式下支持32位Intel指令.此外,如果ELF头表示它是32位可执行文件,64位Linux安装允许运行包含32位指令的ELF.

我想知道是否可以在ELF中放置一些汇编指令,在程序中间将CPU切换到32位兼容模式(然后再返回)?如果内核不允许这些汇编指令,我们是否可以通过某种方式让内核将已经运行的进程切换到32位?

这主要是出于好奇心的问题,因为我无法真正看到任何用例.

linux x86 assembly x86-64 32bit-64bit

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