我正在学习汇编编程.下面是打印'Hello,World!'的简单程序.虽然程序运行完美,但我正在收到警告消息loading
ld:警告:找不到入口符号_start; 默认为0000000008048080
这是代码:
section .data
msg db 'Hello, world!', 0xa
len equ $ - msg
section .text
global main
main:
mov ebx, 1
mov ecx, msg
mov edx, len
mov eax, 4
int 0x80
mov eax, 1
int 0x80
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释这个警告的含义.我使用的是nasm带ubuntu 14.
我有一个Linux x86-32 GAS汇编程序终止如下:
movl $1, %eax
movl $0, %ebx # argument for _exit
int $0x80
Run Code Online (Sandbox Code Playgroud)
当我像这样退出时,程序正常运行,但如果我尝试读取stdout输出,我什么也得不到(使用ie less或wc).
我尝试编译一个最小的C程序并比较strace输出.我发现的唯一区别是,GCC使得C程序(int main() { printf("donkey\n"); })隐含地退出exit_group(0)了strace输出.
我尝试修改我的ASM程序以退出call exit而不是原始系统调用.stdout现在可以正常读取.
测试用例
.data
douout: .string "monkey\n"
.text
.globl main
main:
pushl $douout
call printf
# Exit
movl $1, %eax
movl $0, %ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
编译并运行:
$ yasm -g dwarf2 -f elf -p gas t.asm && gcc -g -melf_i386 -o t t.o && ./t | wc -c
0
Run Code Online (Sandbox Code Playgroud)
预期:
7
Run Code Online (Sandbox Code Playgroud)
编辑:
我打过电话都 …
我想在C程序和要由nasm或yasm编译的程序集文件中包括很多魔术数字。
在纯C语言中,文件看起来像一系列定义,例如:
#define BLESS 55378008
#define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
在nasm或yasm中,相同的include可以实现为:
%define BLESS 55378008
%define ANSWER 42
...
Run Code Online (Sandbox Code Playgroud)
唯一的不同是C和nasm 的define:前面的主角。#%
有什么办法可以编写一个polygot include,它可以让我将它同时包含在C和nasm中,并且只列出一次常量?
是的,我知道我可以使用sed或其他方法从另一个文件生成一个文件。
在汇编程序中,.text加载时0x08048000.在.data与.bss部分来之后.
如果我没有exit在该.text部分中添加系统调用会发生什么?难道导致.data与.bss被解释为代码造成"不可预测"的结果吗?程序何时终止 - 可能在执行每条"指令"之后?
我可以很容易地编写一个程序没有exit系统调用,但如果测试的.data,并.bss会得到执行的是我仍然不知道,因为我想我会知道那是在最罩产生的嘲笑,真正的机器代码.
我认为这个问题更多的是关于CPU和操作系统如何处理这种情况而不是汇编语言.
经过多年的 C++ 和 Python,我昨天决定学习汇编(NASM 语法),我已经对退出程序的方式感到困惑。它主要是关于 ret 因为它是 SASM IDE 上的建议指令。
我显然是在为主要说话。我不关心 x86 向后兼容性。只有 x64 Linux 的最佳方式。我很好奇。
我正在试验并拥有以下汇编代码,它运行得很好,只是在我的程序结束之前我收到了“分段错误(核心转储)”消息:
GLOBAL _start
%define ___STDIN 0
%define ___STDOUT 1
%define ___SYSCALL_WRITE 0x04
segment .data
segment .rodata
L1 db "hello World", 10, 0
segment .bss
segment .text
_start:
mov eax, ___SYSCALL_WRITE
mov ebx, ___STDOUT
mov ecx, L1
mov edx, 13
int 0x80
Run Code Online (Sandbox Code Playgroud)
不管我最后有没有ret;我仍然收到消息。
有什么问题?
我正在使用 x86 和 nasm。
首先,我不了解现代CPU和操作系统。为此,我将针对intel 8085处理器进行解释。当然,我希望你想象有一个操作系统可以在intel 8085上运行。
我们有这样的汇编代码:
MVI A,16
MVI B,16
ADD B
HLT
Run Code Online (Sandbox Code Playgroud)
这段代码非常简单。当此代码运行时,它会执行以下操作: 将数字 16 加载到 intel 8085 处理器的寄存器 a 和 b 中。然后将这两个寄存器的值相加。
当然,当我们尝试在操作系统中运行这段代码时,很可能什么也不会发生。
我想问的是:如何在操作系统上运行不包含任何系统调用(或任何特定于操作系统)的代码(绕过操作系统)?我不希望操作系统在执行此操作时崩溃。