我编写了一个最小函数来测试是否可以调用/链接 C 和 x86_64 汇编代码。
这是我的main.c
#include <stdio.h>
extern int test(int);
int main(int argc, char* argv[])
{
int a = 10;
int b = test(a);
printf("b=%d\n", b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我的test.asm
section .text
global test
test:
mov ebx,2
add eax,ebx
ret
Run Code Online (Sandbox Code Playgroud)
我使用这个脚本构建了一个可执行文件
#!/usr/bin/env bash
nasm -f elf64 test.asm -o test.o
gcc -c main.c -o main.o
gcc main.o test.o -o a.out
Run Code Online (Sandbox Code Playgroud)
我写的时候test.asm并没有任何真正的线索我在做什么。然后我离开并做了一些阅读,现在我不明白我的代码是如何工作的,因为我说服自己它不应该这样。
以下是我认为这不起作用的原因列表:
eaxand传递的ebx。我认为这是不对的。ret可能希望从某个地方获取返回地址。我相当确定我没有提供这个。我所编写的内容产生正确的输出完全是侥幸吗?
我对此完全陌生。虽然我顺便听说过一些 …
所以我试图了解汇编编程如何与堆栈框架等一起工作。
我做了一些练习并使用 GDB 反汇编了一些 C 代码。现在的任务是找出“main”和函数之间的参数传输是如何工作的。我刚刚开始学习,有点迷失了下一个例子实际上在做什么。关于从哪里开始有什么想法或建议吗?
这是一个与教师合作的递归程序。
汇编代码如下所示:
1149: f3 0f 1e fa endbr64
114d: 55 push rbp
114e: 48 89 e5 mov rbp,rsp
1151: 48 83 ec 10 sub rsp,0x10
1155: 89 7d fc mov DWORD PTR [rbp-0x4],edi
1158: 83 7d fc 01 cmp DWORD PTR [rbp-0x4],0x1
115c: 76 13 jbe 1171 <f+0x28>
115e: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
1161: 83 e8 01 sub eax,0x1
1164: 89 c7 mov edi,eax
1166: e8 de ff ff ff call …Run Code Online (Sandbox Code Playgroud) 所以我在汇编中有以下代码:
我知道该函数的参数有两个(x 和 y 或任何字母)。问题是我不知道如何从汇编代码中查看该函数是否返回任何内容,因为它只说ret. 这个函数会被视为 void 或 int 吗?任何有助于理解的解释将不胜感激。
有人可以解释一下_IO_stdin_used下面这一行的内容吗:
114a: 48 8d 3d b3 0e 00 00 lea rdi,[rip+0xeb3] # 2004 <_IO_stdin_used+0x4>
Run Code Online (Sandbox Code Playgroud)
抱歉这个菜鸟问题。
我当前的设置是 m1 MacBook Air。
\n我正在阅读一本低级编程书籍。\n
\n我希望将我编写的 C 代码编译为 x86_64 程序集。
有了 clang 我可以很容易地做到这一点:
\nclang -target x86_64 -masm=intel -S add_two_numbers.c\nRun Code Online (Sandbox Code Playgroud)\n但当我包含一个库(例如 stdio)时它不起作用。
\n\xe2\x9d\xaf clang -target x86_64 -masm=intel -S hello.c\nhello.c:1:10: fatal error: 'stdio.h' file not found\n#include <stdio.h>\n ^~~~~~~~~\nRun Code Online (Sandbox Code Playgroud)\n正如 clang 文档所说,我可以手动安装 x86_64 库并执行以下操作:
\nclang -target x86_64 -masm=intel -I path/to/Include -L path/to/Library -S hello.c\nRun Code Online (Sandbox Code Playgroud)\n但我找不到可在 MacOS 上下载的预构建包。我试过交叉编译,太费力了。
\n所以我放弃了,转而追求更简单的东西。我找到了这个问题的解决方案,我将在下面作为答案分享。
\n我最近面临一个给定的问题:
\n\n\n向量中有8个元素,每个元素都用int8_t表示。
\n在 x86_64 中实现一个算法,将两个向量(uint64_t 类型)相加。
\n添加元素时应考虑饱和算术。
\n例如:
\n80 + 60 = 127
\n(\xe2\x88\x9240) + (\xe2\x88\x92100) = \xe2\x88\x92128
\n
最大的挑战是施加的限制:
\n我想不出任何符合这些限制的解决方案。\n有人能给我一些提示吗?欢迎使用 C 语言的示例。
\n我只能使用“标准”、传输、算术、逻辑指令和标准寄存器:
\n我正在尝试尝试在汇编中写入控制台。我最终使用了 Windows API WriteFile 函数。它运作良好,但我遇到了一个奇怪的怪癖。如果我没有将 rbx 寄存器设置为 [rsp],则 WriteFile 不会返回并给出错误代码 0xC0000005,这是访问冲突错误。它仍然可以正确写入控制台,我觉得这很奇怪。这不是问题,我可以包含一行,没问题。但这让我很困扰,因为我无法弄清楚为什么会出现这种行为。
如果它确实有帮助,我将使用 NASM 和 GCC 来编译我的程序。
这是上下文的完整代码:
bits 64
default rel
extern GetStdHandle
extern WriteFile
extern ExitProcess
section .data
buffer db 0
section .text
print:
push rbp
mov rbp, rsp
add rsp, 8
mov rcx, -11
call GetStdHandle
mov rcx, rax
mov rax, 0x61616161
mov [buffer], rax
mov rdx, buffer
mov r8, 4
mov rbx, [rsp]
call WriteFile
mov rsp, rbp
pop rbp
ret
global main
main:
call print
mov …Run Code Online (Sandbox Code Playgroud) 我有这个任务:
\n\n\n除幂2
\n计算x /2 n,对于 0 \xe2\x89\xa4 n \xe2\x89\xa4 30。向零舍入。
\n\n
\n- 论点1:
\nx- 论据2:
\nn例子:
\n\n
\n- \n
dividePower2(15,1) = 7- \n
dividePower2(-33,4) = -2
这是我到目前为止所得到的,但我不知道我是否朝着正确的方向前进(需要 AT&T 语法):
\n.global dividePower2\n dividePower2:\n sar $2, %esi\n ret\nRun Code Online (Sandbox Code Playgroud)\n 汇编:
.intel_syntax noprefix
.global Foo
Foo:
mov ax, 146
ret
Run Code Online (Sandbox Code Playgroud)
主要.c:
#include <stdio.h>
extern int Foo(void);
int main(int argc, char** args){
printf("Asm returned %d\n", Foo());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在我编译并链接:
(compiler name) -c asm.s -o asm.o
(compiler name) asm.o main.c -o main
./main
Run Code Online (Sandbox Code Playgroud)
我正在使用 Windows 和 LLVM 的 x64 windows 二进制文件。
GCC 打印 146(如预期),但 clang 生成的代码打印随机值,为什么?在 Windows 上使用 gdb 调试 clang 二进制文件显然存在一些问题,因此我无法提供任何 gdb 日志。GCC 二进制文件正在执行我期望的操作,但不是 Clang。
我在 Visual Studio IDE 的调试器上从 C++ 构建中获得了以下反汇编代码:
根据我在movss指令上看到的内容,应该是
因此,虽然前 3 个字节很容易理解,但我不太理解其余的字节,例如05 6b 02 10 00第一行、44 24 38第二行等等。
你能帮我理解它们吗?05或44好像是/r?这是什么意思?