Articles of 程序集

这个方法好吗?

对于某些function,我需要切换堆栈,以便原始堆栈保持不变。 为此,我写了两个macros,如下所示。 #define SAVE_STACK() __asm__ __volatile__ ( "mov %%rsp, %0; mov %1, %%rsp" : \ "=m" (saved_sp) : "m" (temp_sp) ); #define RESTORE_STACK() __asm__ __volatile__ ( "mov %0, %%rsp" : \ "=m" (saved_sp) ); 这里temp_sp和saved_sp是线程局部variables。 temp_sp指向我们使用的临时堆栈。 对于一个原来的堆栈我想要修改的函数,我把SAVE_STACK放在开头,RESTORE_STACK放在最下面。 例如,像这样。 int some_func(int param1, int param2) { int a, b, r; SAVE_STACK(); // Function Body here ………………… RESTORE_STACK(); […]

我如何分解原始的MIPS代码?

类似于如何反汇编原始x86代码? ,但是对于MIPS架构:如何用objdump反汇编原始MIPS代码? 我想检查vmlinux映像中的说明,但要做到这一点,我现在必须: : > xc mipsel-linux-gnu-gcc -c -o xo xc mipsel-linux-gnu-objcopy –add-section raw=vmlinux xo mipsel-linux-gnu-objcopy –remove-section .comment xo mipsel-linux-gnu-objdump -D xo | less 有没有更简单的方法来做到这一点? 我已经尝试了下面的无济于事: mipsel-linux-gnu-objdump -b elf32-tradlittlemips -mmips -Mgpr-names=O32,cp0-names=mips1,cp0-names=mips1,hwr-names=mips1,reg-names=mips1 -D vmlinux | less 它只是吐出来: mipsel-linux-gnu-objdump: vmlinux: File format not recognized 如果有帮助,下面是一些命令的输出: $ file xo xo: ELF 32-bit LSB relocatable, MIPS, MIPS-I version 1 […]

缺lessgdb和nasm的debugging信息

我有一个简单的汇编程序,下面的makefile: all : calc calc : calc.o gcc -m32 -g -o calc calc.o calc.o : calc.s nasm -f elf -g -F stabs calc.s 我尝试使用gdb进行debugging,但总是说: 单步执行,直到退出函数asc2int,没有行号信息。 我尝试了很多解决scheme,包括-F dwarf但没有一个-F dwarf 。 你能帮我解决这个问题吗?

为什么gcc生成详细的汇编代码?

我有一个关于GCC(-S选项)生成的汇编代码的问题。 因为,我对汇编语言很陌生,对它知之甚less,所以这个问题将是非常原始的。 不过,我希望有人会回答: 假设,我有这个C代码: main(){ int x = 15; int y = 6; int z = x – y; return 0; } 如果我们看一下汇编代码(尤其是对应于int z = x – y的部分),我们可以看到: 主要: … subl $16, %esp movl $15, -4(%ebp) movl $6, -8(%ebp) movl -8(%ebp), %eax movl -4(%ebp), %edx movl %edx, %ecx subl %eax, %ecx movl %ecx, %eax movl […]

在用户空间的x86-64 Linux上的CS和SS寄存器的含义?

内核在第一个入口载入本地用户级Linux应用程序之后,x86-64 CPU寄存器几乎为零,除了具有通常含义的RSP和RIP之外,寄存器CS SS和R11非零: cs 0x33 51 ss 0x2b 43 r11 0x200 512 我的理解是CS和SS寄存器在x86-64上是未使用的,因为在长模式下我们有一个64位的地址模型。 CS和SS寄存器意味着什么从/到内核? userland是否期望让他们孤单? R11中的初始512值是什么意思?

如何让asm跳转到c中的variables地址?

现在,我使用c中的内联汇编来调用跳转指令,如下所示: int register eax asm("eax") = addr; // addr is a memory address asm("jmp *%eax"); 我想这样做,而不必设置任何其他的寄存器值(例如,我想要做的就是这样): asm("jmp *(addr)"); 什么是正确的方法来做到这一点? 也就是说,如何“插入”acvariables到asm调用? Ubuntu 12.04 64位,Intel x86 64位处理器,gcc 4.7.4版本。

为什么这个简单的汇编程序使用AT&T语法,而不是英特尔语法?

这段代码有什么问题(在x86_64 Linux上运行)? .intel_syntax .text .globl _start _start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 14 syscall mov rax, 60 mov rdi, 0 syscall .data msg: .ascii "Hello, world!\n" 当我运行它时: $ clang -o hello_intel hello_intel.s -nostdlib && ./hello_intel 没有输出。 让我们来看看它: $ strace ./hello_intel execve("./hello_intel", ["./hello_intel"], [/* 96 vars */]) = 0 write(1, […]

我如何使用中断触发x86程序集中的除零错误exception?

我想了解x86程序集中的中断。 我试图触发一个除零错误,这对应于代码0。 int $0 我期待这样的行为除以零。 movl $0, %edx # dividend movl $0, %eax # dividend movl $0, %edi # divisor divl %edi 在前一种情况下,我的程序在Linux上崩溃,出现“分段错误”并退出代码139。 在后一种情况下,我的程序在Linux上出现“浮点exception”并退出代码136。 如何使用中断触发与使用零除数的div指令相同的错误?

NASM参数的长度

我正在编写一个简单的程序来显示用户提供的名称。 结果是我应该可以input命令并获得预期的结果。 命令 ./hello John 结果 Hello, John. 然而,当程序转到显示名称时,它不会。 我相信这与计算论证的长度有关。 请大家看看我的代码,告诉我你的想法? ; hello.asm ; ; Assemble: nasm -f elf hello.asm ; Link: ld -o hello hello.o ; Run: ./hello <name> section .data period: db ".", 10 periodLen: equ $-period helloMsg: db "Hello, " helloMsgLen: equ $-helloMsg usageMsg: db "Usage: hello <name>", 10 usageMsgLen: equ $-usageMsg […]

导致缓冲区溢出,segfault

我试图在下面,非常简单的程序导致缓冲区溢出: #include <stdio.h> #include <stdint.h> void badf(int n, char c, char* buffer) { char mycode[] = { 0xeb, 0x0f, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x8b, 0x1c, 0x24, 0x8d, 0x0c, 0x24, 0x31, 0xd2, 0xcd, 0x80, 0xe8, 0xec, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; […]