这有点奇怪,但今天我正在寻找GNU汇编程序(我希望能够至少阅读语法),并且试图让我的这个有点人为的例子工作.也就是说我只想从0到100,一直打印数字.几分钟后,我想出了这个:
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
movl $0, %eax # The starting point/current value.
movl $100, %ebx # The ending point.
_loop:
# Display the current value.
pushl %eax
pushl $string
call _printf
addl $8, %esp
# Check against the ending value.
cmpl %eax, %ebx
je _end
# Increment the current value.
incl %eax
jmp _loop
_end:
Run Code Online (Sandbox Code Playgroud)
我从中得到的只是一遍又一遍地打印出来.就像我说的,只是一个有点人为的例子,所以不要太担心它,这不是生死攸关的问题.
(格式有点混乱,但没什么大不了的).
0x004012d0 <main+0>: push %ebp
0x004012d1 <main+1>: mov %esp,%ebp
0x004012d3 <main+3>: sub $0x28,%esp
Run Code Online (Sandbox Code Playgroud)
如果地址不可用,我们可以自己计算吗?
我的意思是我们只有这个:
push %ebp
mov %esp,%ebp
sub $0x28,%esp
Run Code Online (Sandbox Code Playgroud) 我正在为基于ARM-Cortex M3的设备编写启动脚本.如果我编译汇编程序启动脚本和C应用程序代码然后组合目标文件并将它们传输到我的设备一切正常.
但是,如果我使用ar创建存档(libboot.a)并将该存档与C应用程序组合,则会出现问题:
我把启动代码放在一个部分:
.section .boot, "ax"
.global _start
_start:
.word 0x10000800 /* Initial stack pointer (FIXME!) */
.word start
.word nmi_handler
.word hard_fault_handler
... etc ...
Run Code Online (Sandbox Code Playgroud)
我发现ld从最终的二进制文件中剥离了这个("boot"部分不可用).这是非常自然的,因为它不ld知道它的依赖性,但它会导致设备无法正确启动.
所以我的问题是:强制包含此代码的最佳方法是什么?
假设我有如下函数:
# cat 003.c
int foo(int a, int b)
{
return a+b;
}
Run Code Online (Sandbox Code Playgroud)
并像这样编译它:
gcc -S 003.c
Run Code Online (Sandbox Code Playgroud)
得到以下汇编结果:
.file "003.c"
.text
.globl foo
.type foo, @function
foo:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
addl %edx, %eax
leave
ret
.LFE2:
.size foo, .-foo /* size of the function foo, how to get it?*/
Run Code Online (Sandbox Code Playgroud)
上面的最后一行确实得到了函数的大小.编译器在哪里存储大小?我可以使用C或内联asm在我的原始C程序中以某种方式获取函数的大小吗?
我正在尝试生成16位DOS可执行文件,但使用gcc编译器.所以我使用古老的gcc-4.3 ia16端口.我制作了我的构建的Docker镜像:https://registry.hub.docker.com/u/ysangkok/ia16-gcc-rask
这是我正在尝试的:
host $ mkdir results
host $ docker run -v $PWD/results:/results -it ysangkok/ia16-gcc-rask
container $ cd results
Run Code Online (Sandbox Code Playgroud)
我没有包含头文件,导致gcc无法使用OpenWatcom的libc头文件.
container $ echo 'main() { printf("lol"); }' > test.c
Run Code Online (Sandbox Code Playgroud)
我没有链接因为我没有16位binutils可用.如果我构建一个目标文件,它没有正确标记为16位.
container $ /trunk/build-ia16-master/prefix/bin/ia16-unknown-elf-gcc -S test.c
Run Code Online (Sandbox Code Playgroud)
现在我有这个汇编文件:
.arch i8086,jumps
.code16
.att_syntax prefix
#NO_APP
.section .rodata
.LC0:
.string "lol"
.text
.p2align 1
.global main
.type main, @function
main:
pushw %bp
movw %sp, %bp
subw $4, %sp
call __main
movw $.LC0, %ax
pushw %ax
call printf
addw $2, %sp
movw …Run Code Online (Sandbox Code Playgroud) 我正在研究linux内核源码(旧版本0.11v).当我检查fork系统调用时,有一些asm代码用于上下文切换,如下所示:
/*
* switch_to(n) should switch tasks to task nr n, first
* checking that n isn't the current task, in which case it does nothing.
* This also clears the TS-flag if the task we switched to has used
* tha math co-processor latest.
*/
#define switch_to(n) {\
struct {long a,b;} __tmp; \
__asm__("cmpl %%ecx,current\n\t" \
"je 1f\n\t" \
"movw %%dx,%1\n\t" \
"xchgl %%ecx,current\n\t" \
"ljmp *%0\n\t" \
"cmpl %%ecx,last_task_used_math\n\t" \
"jne 1f\n\t" \
"clts\n" \
"1:" \
::"m" …Run Code Online (Sandbox Code Playgroud) 我正在学习如何创建组装和链接的真实模式程序:
我使用没有指定前缀的Intel语法 .intel_syntax noprefix
我想将字符串的地址加载到SI寄存器中.我知道,如何在NASM中引用内存位置,但是当我在GNU汇编程序代码中执行相同操作时,它只将字符串的WORD移动到寄存器而不是标签的地址.
我的代码是:
.code16
.intel_syntax noprefix
mov cx, 11
mov si, name
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)
当我用GCC编译它时,我可以在调试器中看到处理器执行的操作:
mov si, WORD ptr ds:0x7d2d
Run Code Online (Sandbox Code Playgroud)
但我想将字符串的地址移入寄存器,而不是它指向的数据.
我还尝试在名称周围放置方括号,如下所示:
.code16
.intel_syntax noprefix
mov cx, 11
mov si, [name]
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)
它没有任何区别.
从NASM我知道这个汇编代码有效:
mov si, name
Run Code Online (Sandbox Code Playgroud)
NASM将生成将地址移动name到寄存器SI的指令.
我的问题:有没有办法强制GCC使用带有无前缀的英特尔语法将符号的地址加载到寄存器中?
我正在尝试构建 Gnu binutils,通过定义宏SYSV386_COMPAT 0来改变它生成一些 FPU 操作码的方式,从而解锁行为。
我可以轻松地进入头文件并手动设置值,但是如何调用配置脚本才能#define SYSV386_COMPAT 0在命令行上指定等效项?如果可能的话,我更愿意在命令行上指定一些内容(只是因为该功能是可传递的,而且我认为我不应该破解源代码)。话虽如此,我已经尝试阅读至少一些 FM,但未能在或AC_DEFINE(SYSV386_COMPAT, 0)中插入。binutils/configure.ingas/configure.in
假设我有以下汇编代码:
.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 …