有没有办法从C#代码生成汇编代码?我知道C代码可以使用GAS,但有人知道C#是否可行?
我正在尝试构建 Gnu binutils,通过定义宏SYSV386_COMPAT 0来改变它生成一些 FPU 操作码的方式,从而解锁行为。
我可以轻松地进入头文件并手动设置值,但是如何调用配置脚本才能#define SYSV386_COMPAT 0在命令行上指定等效项?如果可能的话,我更愿意在命令行上指定一些内容(只是因为该功能是可传递的,而且我认为我不应该破解源代码)。话虽如此,我已经尝试阅读至少一些 FM,但未能在或AC_DEFINE(SYSV386_COMPAT, 0)中插入。binutils/configure.ingas/configure.in
我一直在阅读“从头开始编程”一书来学习 Linux 中的汇编编程。我在解决第 3 章末尾的一个练习时遇到了麻烦。练习说修改以下程序以使用数据集末尾的地址来终止循环。这只是一个简单的程序,用于查找一组数据中的最大数字,目前它只是使用数字零来标记数据的结尾。
#PURPOSE: This program finds the maximum number of a
# set of data items.
#
#VARIABLES: The registers have the following uses:
#
# %edi -- Holds the index of the data item being examined
# %ebx -- Largest data item found
# %eax -- Current data item
#
# The following memory locations are used:
#
# data_items -- Contains the item data. A 0 is used
# to terminate the data.
#
.section …Run Code Online (Sandbox Code Playgroud) 假设我有以下汇编代码:
.section .text
.globl _start
_start:
Run Code Online (Sandbox Code Playgroud)
如果我使用以下命令创建了一个可执行文件:
as 1.s -o 1.o
ld 1.o -o 1
Run Code Online (Sandbox Code Playgroud)
GNU 汇编器是否会将其自己的入口点添加到我的可执行文件中,该可执行文件调用_start或将_start成为实际的入口点?
请参阅此问题了解更多详细信息。
GNU 汇编器在汇编 Intel 语法代码时给出了意外的内存操作数。
我已将 bug 减少到一行代码,在过去的三天里,我尝试了一切方法来理解为什么 GNU 汇编器会产生一些我无法理解的东西。我知道这一定(或应该)是微不足道的,但我不知所措。
以下文本位于文件 code.asm 中:
.intel_syntax noprefix
.global somecode
somecode:
int 3
mov rax,qword [rcx]
ret
.att_syntax
Run Code Online (Sandbox Code Playgroud)
使用以下命令汇编和反汇编 code.asm:
as code.asm -o code1.obj -64
objdump -Mintel -d code1.obj > code1.asm
Run Code Online (Sandbox Code Playgroud)
code1.asm(带有反汇编代码)的内容是:
code1.obj: file format pe-x86-64
Disassembly of section .text:
0000000000000000 <somecode>:
0: cc int3
1: 48 8b 41 08 mov rax,QWORD PTR [rcx+0x8]
5: c3 ret
Run Code Online (Sandbox Code Playgroud)
我正在使用 GNU 汇编器 (GNU Binutils) 2.25 (`x86_64-pc-cygwin')。
问题:为什么内存操作数 QWORD PTR [rcx+0x8] 中有一个额外的 1 个 qword 偏移量(8 …
我在 64 位 Linux 环境中运行我的代码,其中 Linux 内核是使用IA32_EMULATION和X86_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) 我正在用汇编编写引导加载程序,它似乎在 qemu、bochs 和 virtualbox 上运行良好。但是,它并没有在真实硬件上加载内核(似乎)。
引导加载程序首先将一个字符写入视频内存(用于调试),然后从驱动器读取扇区 2 并远跳转到内核。然后内核将一些字符写入视频内存。
在真机上,我在屏幕上看到引导加载程序中的字符,它挂在那里(闪烁的插入符号)。
我已经尝试将 DS、ES、SI 设置为零,并且我也在设置堆栈段。
我正在使用 bios int 13 function 2 从驱动器读取扇区 2。我有点怀疑它与驱动器编号有关。我都尝试使用在启动时(在 dl 中)传递给引导加载程序的驱动器号,并将其手动设置为 0x0、0x80 和 0x81。
我注意到的一件奇怪的事情是,我用来接近跳转的标签神奇地获得了正确的地址。使用 objdump 我看到例如:jmp 0x2,而使用 gdb 和 qemu,它说:jmp 0x7c02。CS 和所有其他段寄存器为零。无论我在链接中使用 -Ttext 0x0 还是 -Ttext 0x7c00,引导加载程序在所有模拟器上都能正常工作。当我与 -Ttext 0x7c00 链接时,objdump 说 jmp 0x7c02。
编辑,引导加载程序如下所示:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0, %sp
movb $2, …Run Code Online (Sandbox Code Playgroud) 所以我正在研究Redox OS(一个用 Rust 制作的操作系统)的源代码,看看我是否能学到一些东西。
我读的汇编文件的start.s中bootloader的文件夹。在interrupt_vector_table标签中,我们有:
interrupt_vector_table:
b . @ Reset
b .
b . @ SWI instruction
b .
b .
b .
b .
b .
Run Code Online (Sandbox Code Playgroud)
究竟是b .什么?
我不是一个完整的组装初学者,我以前从未遇到过这种情况。
我正在为内核编写 GDT 并且一切顺利,我正在关注本教程。
http://www.osdever.net/bkerndev/Docs/gdt.htm
当将 C 代码链接到汇编代码时,他使用这段代码。
; This will set up our new segment registers. We need to do
; something special in order to set CS. We do what is called a
; far jump. A jump that includes a segment as well as an offset.
; This is declared in C as 'extern void gdt_flush();'
global _gdt_flush ; Allows the C code to link to this
extern _gp ; Says that '_gp' is in another file
_gdt_flush: …Run Code Online (Sandbox Code Playgroud) x86 汇编设计有指令后缀,如l(long), w(word), b(byte)。
所以我认为这jmpl是long jmp
但是当我编译它时它的工作很奇怪。
见下面的例子。
测试1:组装
main:
jmp main
Run Code Online (Sandbox Code Playgroud)
测试1:编译结果
eb fe jmp 0x0804839b <main>
Run Code Online (Sandbox Code Playgroud)
测试2:组装
main:
jmpl main # added l suffix
Run Code Online (Sandbox Code Playgroud)
测试2:编译结果
ff 25 9b 83 04 08 jmp *0x0804839b
Run Code Online (Sandbox Code Playgroud)
与Test1相比,Test2的结果出乎意料。
我认为它应该与Test1一样编译。
问:
是jmpl什么不同的指令在8086的设计?
(根据这里,jmpl在 SPARK 中意味着 jmp 链接。是这样的吗?)
...或者这只是 gnu 汇编程序上的错误?