我有一个ARM汇编代码,可以很好地编译Visual Studio.我想现在使用相同的ARM汇编代码并使用GNU Assembler进行编译.如您所知,两个汇编程序的语法都不同.我想知道是否有任何工具可以从这些汇编语法转换.
我决定在暑假期间学习x86组装会很有趣.所以我从一个非常简单的hello world程序开始,借用免费的例子gcc -S可以给我.我最终得到了这个:
HELLO:
.ascii "Hello, world!\12\0"
.text
.globl _main
_main:
pushl %ebp # 1. puts the base stack address on the stack
movl %esp, %ebp # 2. puts the base stack address in the stack address register
subl $20, %esp # 3. ???
pushl $HELLO # 4. push HELLO's address on the stack
call _puts # 5. call puts
xorl %eax, %eax # 6. zero %eax, probably not necessary since we didn't do anything with …Run Code Online (Sandbox Code Playgroud) 我有一个使用as编译的目标文件(来自汇编程序代码).
如果我使用ld链接它,当我尝试stepi(或nexti)gdb抱怨地址0x0的内存访问.如果我使用gcc链接它,一切都很好.
我猜这个问题是由ld引起的,与gcc的链接结果相比,它产生的部分更少.
有没有办法配置gdb更冗长,所以我可以弄清楚可执行文件有什么问题?
(gdb) b main
Breakpoint 1 at 0x100000f8e
(gdb) r
Breakpoint 1, 0x0000000100000f8e in main ()
(gdb) x/10i $pc
0x100000f8e <main>: fbld 0x6c(%rip) # 0x100001000 <data1>
0x100000f94 <main+6>: fimul 0x7a(%rip) # 0x100001014 <data2>
0x100000f9a <main+12>: fbstp 0x60(%rip) # 0x100001000 <data1>
0x100000fa0 <main+18>: mov0x0 $0x2000001,%rax
0x100000fa7 <main+25>: mov $,%rdi
0x100000fae <main+32>: syscall
(gdb) si
Cannot access memory at address 0x0
0x0000000100000f94 in main () …Run Code Online (Sandbox Code Playgroud) 我想写一个气体宏来生成包含xmm寄存器的各种movdqu指令的代码,具体取决于参数n.
.macro xxmov n, p1
.if (\n == 1)
xor %eax, %eax
.endif
.if (\n - 1)
xxmov (\n - 1), \p1
.endif
movdqu ((\n - 1)*0x10)(\p1), %xmm0
.endm
xxmov 14, %rsi
Run Code Online (Sandbox Code Playgroud)
编译后,反汇编的代码是,
0000000000000000 <.text>:
0: 31 c0 xor %eax,%eax
2: f3 0f 6f 06 movdqu (%rsi),%xmm0
6: f3 0f 6f 46 10 movdqu 0x10(%rsi),%xmm0
b: f3 0f 6f 46 20 movdqu 0x20(%rsi),%xmm0
10: f3 0f 6f 46 30 movdqu 0x30(%rsi),%xmm0
15: f3 0f 6f 46 40 movdqu 0x40(%rsi),%xmm0
1a: …Run Code Online (Sandbox Code Playgroud) 一直通过AT&T语法关注youtube上的汇编教程。我刚刚学习了使用.type指令声明(如果在这里是正确的术语)函数,例如:
.type MyFunction, @function
Run Code Online (Sandbox Code Playgroud)
现在,我可以像下面这样定义我的函数:
MyFunction:
<code here>
Run Code Online (Sandbox Code Playgroud)
然后在任何时候调用它:
call MyFunction
Run Code Online (Sandbox Code Playgroud)
我知道在教程之前,我们只是在创建一个附加到一些代码的标签:
MyLabel:
<code here>
Run Code Online (Sandbox Code Playgroud)
然后可以这样称呼它:
call MyLabel
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
用.type声明的函数和仅用标签声明的'function'到底有什么区别?什么时候应该使用另一个,或者这有关系吗?
在修改程序集中编写bootsector代码之后,我想知道我是否可以在C中执行相同操作.到目前为止,空函数中的代码生成如下:
在C:
void _start() {
halt:
goto halt;
}
Run Code Online (Sandbox Code Playgroud)
随后的asm(由GCC生成):
7c00: 55 push %bp
7c01: 89 e5 mov %sp,%bp
7c03: eb fe jmp 0x7c03
Run Code Online (Sandbox Code Playgroud)
但是,是否可以指定对于此(入口)函数,我不希望初始化基本和堆栈指针?BIOS将控制权直接传输到0x7c00,因此设置堆栈指针的前两条指令是冗余的.
我已经尝试添加__attribute__ ((always_inline, noreturn, regparm(0)))到函数声明,但似乎没有做任何事情.
系统我在:
/tmp/jonesforth $ cat /etc/issue
Ubuntu 16.04.1 LTS \n \l
Run Code Online (Sandbox Code Playgroud)
这是一个32位系统.
从annexia存储库中克隆:
git clone git://git.annexia.org/git/jonesforth.git
Run Code Online (Sandbox Code Playgroud)
构建顺利:
cd jonesforth
/tmp/jonesforth $ make
gcc -m32 -nostdlib -static -Wl,-Ttext,0 -o jonesforth jonesforth.S
Run Code Online (Sandbox Code Playgroud)
然而,测试没有通过:
/tmp/jonesforth $ make test
test_stack_trace.f ... --- .test_stack_trace.test 2016-09-17 17:44:59.488492834 -0500
+++ test_stack_trace.f.out 2016-09-17 17:33:11.171189490 -0500
@@ -0,0 +1,6 @@
+TEST4+0 TEST3+0 TEST2+0 TEST+0
+3
+TEST4+0 TEST3+32 TEST2+0 TEST+0
+TEST4+0 TEST3+0 TEST2+4 TEST+0
+3
+TEST4+0 TEST3+32 TEST2+4 TEST+0
Makefile:34: recipe for target 'test_stack_trace.test' failed
make: *** [test_stack_trace.test] Error 1
Run Code Online (Sandbox Code Playgroud)
启动jonesforth会导致分段错误: …
我刚刚开始学习ARM程序集,我不明白为什么GNU as语法与x86*不同.
由于指令是相同的,我会期望一切都像x86*,除了指令本身,但相反,我正在努力加载字符串的地址,等等.我从头开始通过在线阅读一些PDF ,man 2 syscall并反编译基本的例子,因为我不确定我可以在网上找到的各种Hello World的价值.
我的问题:
%印记#或一个$sigil.事实上,如果我编译mov r0, $0,objdump -D给我一个回复mov r0, #1.一切都汇集到了同样的东西mov r0, #1:
mov %r0, $1
10080: e3a00001 mov r0, #1
mov r0, $1
10084: e3a00001 mov r0, #1
mov %r0, #1
10088: e3a00001 mov r0, #1
mov r0, #1
1008c: e3a00001 mov r0, #1
Run Code Online (Sandbox Code Playgroud)
我无法直接使用标签的地址来加载字符串地址,所以我需要使用一个变量.mov r1, $hello或者ldr r1, $hello不工作.在x86_64中,我会写的mov $hello, %rsi.所以我正在做gcc所做的事情,我正在用另一个标签的地址创建一个单词.
我无法放置我的常量 …
我正在使用 GAS 为 ARM Linux 构建程序,但我想做一些宏以使我的开发更加智能。那我想知道:
我怎么能为此做一个宏:(x+y*240)*2, wasx和yare int,它将像这样使用:
mov r0, MACRO_SHOULD_BE_CALLED_HERE
Run Code Online (Sandbox Code Playgroud)
我怎么能做一个应该像这样调用的宏:
JUST_MACRO_CALLED_HERE_TO_DO_SOMETHING
Run Code Online (Sandbox Code Playgroud)
这只会做一些已经在其中定义的事情,例如打印功能。
另外,如果我需要宏或函数调用的一些参数。我怎么能做到?
PS:r0是一个ARM寄存器,比如eaxx86
两段示例代码;首先是一些调用程序集的 C++ 代码:
/* test1.cc */
#include <stdio.h>
extern "C" void blah();
extern "C" void stuff() {
printf( "This is a test\n" );
}
int main( int argc, char *argv[] ) {
blah();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
...然后大会:
.file "test2.s"
.text
.globl blah, stuff
.type blah,@function
.type stuff,@function
.align 16
blah:
/* normal function preamble */
pushl %ebp
movl %esp, %ebp
label1:
call stuff
leave
retn
Run Code Online (Sandbox Code Playgroud)
内置:
as -g --32 test2.s -o test2.o
clang++ -m32 -g test1.cc -c
clang++ -m32 -g …Run Code Online (Sandbox Code Playgroud)