什么是更好的:void foo()或void foo(void)?随着虚空,它看起来丑陋和不一致,但我被告知它是好的.这是真的?
编辑:我知道一些旧的编译器做了奇怪的事情,但如果我只使用GCC,那void foo()好吗?将foo(bar);随后被接受?
以下链接解释了UNIX(BSD风格)和Linux的x86-32系统调用约定:
但是UNIX和Linux上的x86-64系统调用约定是什么?
有什么区别
int x=7;
Run Code Online (Sandbox Code Playgroud)
和
register int x=7;
Run Code Online (Sandbox Code Playgroud)
?
我正在使用C++.
int max(int n, ...)
Run Code Online (Sandbox Code Playgroud)
我正在使用cdecl调用约定,其中调用者在被调用者返回后清理变量.
我想知道怎么做宏va_end,va_start和va_arg工作?
调用者是否将参数数组的地址作为max的第二个参数传递?
假设我在寄存器中有一个整数,我该如何打印?你能展示一个简单的示例代码吗?
我已经知道如何打印一个字符串,如"你好,世界".
我正在Linux上开发.
我正在努力学习为64位Mac OS编写汇编语言.我对32位Mac OS以及32位和64位Linux没有任何问题.
但是,Mac OS 64位是不同的,我无法弄清楚.因此,我在这里寻求帮助.
我没有使用系统调用打印的问题.但是,我想学习如何使用Mac OS的64位汇编语言调用C函数.
请查看以下代码
.data
_hello:
.asciz "Hello, world\n"
.text
.globl _main
_main:
movq $0, %rax
movq _hello(%rip), %rdi
call _printf
Run Code Online (Sandbox Code Playgroud)
我使用$ gcc -arch x86_64 hello.s
组装和链接.
它生成二进制代码.但是,运行它时出现了分段错误.
我在调用_printf之前尝试添加"subq $ 8,%rsp",仍然和以前一样.
我做错了什么?
顺便说一下,这是在Mac上调试此代码的任何方法吗?我尝试添加-ggdb或-gstab或-gDWARF和$ gdb ./a.out,但无法查看代码并设置断点.
我正在关注Linux 64系统中的《开始x64汇编编程》一书。我正在使用 NASM 和 gcc。
在关于浮点运算的章节中,本书指定了以下用于添加 2 个浮点数的代码。在本书和其他在线资源中,我读到寄存器 RAX 根据调用约定指定要使用的 XMM 寄存器的数量。
书中的代码如下:
extern printf
section .data
num1 dq 9.0
num2 dq 73.0
fmt db "The numbers are %f and %f",10,0
f_sum db "%f + %f = %f",10,0
section .text
global main
main:
push rbp
mov rbp, rsp
printn:
movsd xmm0, [num1]
movsd xmm1, [num2]
mov rdi, fmt
mov rax, 2 ;for printf rax specifies amount of xmm registers
call printf
sum:
movsd xmm2, [num1]
addsd xmm2, [num2]
printsum:
movsd …Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include <stdio.h>
void foo() {
printf("Hello world\n");
}
void bar() {
printf("Hello world");
}
Run Code Online (Sandbox Code Playgroud)
这两个函数产生的程序集是:
.LC0:
.string "Hello world"
foo():
mov edi, OFFSET FLAT:.LC0
jmp puts
bar():
mov edi, OFFSET FLAT:.LC0
xor eax, eax
jmp printf
Run Code Online (Sandbox Code Playgroud)
现在我知道puts 和 printf之间的区别,但我发现这很有趣,因为 gcc 能够内省 const char* 并确定是调用 printf 还是 puts。
另一个有趣的事情是bar,编译器将返回寄存器 ( eax)清零,即使它是一个void函数。为什么它在那里而不是在里面foo?
我假设编译器“内省了我的字符串”是否正确,或者对此有另一种解释?
让我们采用以下基本 C 函数及其生成的故意未优化的程序集:
int main() {
int i = 4;
return 3;
}
Run Code Online (Sandbox Code Playgroud)
它产生以下(未优化的)程序集,这对我来说都是有意义的:
main:
pushq %rbp
movq %rsp, %rbp
movl $4, -4(%rbp)
movl $3, %eax
popq %rbp
ret
Run Code Online (Sandbox Code Playgroud)
然而,当我添加一个函数调用时,有两条指令我不太明白:
void call() {};
int main() {
int i = 4;
call();
return 3;
}
Run Code Online (Sandbox Code Playgroud)
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp <-- why is it subtracting 16?
movl $4, -4(%rbp)
movl $0, %eax <-- why is it first clearing the %eax register?
call call
movl $3, %eax
leave …Run Code Online (Sandbox Code Playgroud)