这需要在纯汇编中完成(即没有库或调用C).
我理解问题的本质:需要将整数除以10,将一位数的余数转换为ASCII,然后输出,然后用商重复该过程.
但由于某种原因,它只是不起作用.我在x86上使用NASM.
这是我现在所拥有的(不输出任何内容,但也不会抛出任何汇编错误):
; integer to output is stored in eax
mov ecx, 10 ; for base 10
loop:
div ecx ;EAX contains the quotient, EDX the remainder
; Do something to EDX to convert it to ASCII, not sure if this is correct
add edx, '0'
push eax ;We'll be playing with EAX to output EDX, save EAX to the stack
mov eax, 4 ; sys_write
mov ebx, 1 ; to STDOUT
mov ecx, edx
mov edx, 1 …Run Code Online (Sandbox Code Playgroud) 我一直在尝试设计一个简单的操作系统,只是引导扇区,以及带有中断的16位实模式.我终于能够制作OS/bootloader,我在虚拟盒中进行了测试,并且它有效.
然后我将图像刻录到CD上,并将其启动到我的旧桌面,使用Pentium 4,BIOS修订版A05和1GB内存,并且它工作得很好 - 一个简单的操作系统,在顶部打印一个"标题"屏幕,所有它允许您键入屏幕,注册几个键导航光标.
然后我将光盘插入我1年前的笔记本电脑,配备i5处理器,2.6 GB RAM和A05 BIOS Revision,光标似乎随机移动,高速打印随机字符,最后停在anscii字符处235(扩展字符表的一部分),此时键盘工作正常,指定移动光标的键工作正常,只是标题.这是我测试它的计算机,对其进行了编译,编写并将其刻录成CD.(我使用Linux Mint 12 OS)
我已经跳过了我认为需要做的所有"箍":制作了一个iso图像,遵循El Torito'无仿真'启动标准,启动签名,512字节,并写入正确的扇区.
这是我的代码的问题,我没有做某事,或者这是正常的吗?
这是我的代码(NASM x86语法):
;**************************
; Note OS, Experimental OS
;**************************
[org 0x7C00]
[bits 16]
start:
jmp loader ;jump to the actual start of bootloader
times 8 - ($ - $$) db 0 ;pad eight bytes
;*********************
;El Torito Boot Info Table
;*********************
;in nasm, I couldn't figure out how to reserve bytes, in the middle of .text
;so I zeroed it out.
times 56 db …Run Code Online (Sandbox Code Playgroud) 我有一个NASM程序集文件,我正在组装和链接(在Intel-64 Linux上).
有一个文本文件,我希望文本文件的内容出现在生成的二进制文件中(基本上是一个字符串).二进制文件是ELF可执行文件.
我的计划是在ELF文件中创建一个新的只读数据部分(相当于传统.rodata部分).
理想情况下,会有一个工具来逐字添加文件作为elf文件中的新部分,或者是一个逐字包含文件的链接器选项.
这可能吗?
我目前正在使用llc将.ll文件转换为.s使用命令行的文件。然后我想获取这个文件,然后使用nasm从它创建一个可执行文件。虽然第一步似乎工作正常,但我无法让第二步工作。
原始文件被调用code.ll并包含以下代码:
define i32 @main() {
ret i32 0
}
Run Code Online (Sandbox Code Playgroud)
现在我使用 cmd.s通过键入以下内容来构建文件:
有限责任公司代码.ll
这工作正常并创建一个code.s包含以下代码的文件:
.def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
@feat.00 = 1
.def _main;
.scl 2;
.type 32;
.endef
.text
.globl _main
.align 16, 0x90
_main: # @main
# BB#0:
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
现在我想使用这段代码创建一个可执行文件,关于它的llc 文档告诉我:
然后,汇编语言输出可以通过本机汇编器和链接器来生成本机可执行文件。
因此,我 通过键入以下内容使用nasm(据我所知,它应该可以满足我的要求):
nasm 代码.s
这会产生以下错误列表:
code.s:1: error: attempt to …Run Code Online (Sandbox Code Playgroud) 在以下 x86 汇编代码中:
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002+0x00)
Run Code Online (Sandbox Code Playgroud)
这些值似乎没有分配给任何变量。那么这段代码有什么作用呢?我听说过它被存储在内存中,但具体在哪里呢?
我正在开发一个简单而小型的64位操作系统。到目前为止,我只使用一个文件,并使用NASM进行编译:
nasm -f bin os.asm -o os.bin
Run Code Online (Sandbox Code Playgroud)
然后.bin用qemu 测试文件。
现在,我需要在文件中使用多个os.bin文件。我插入了这一行:
extern helper_func
Run Code Online (Sandbox Code Playgroud)
然后在代码中调用它。在另一个.asm文件中,我创建了此函数或过程。问题是bin格式不支持extern,因此我尝试使用ELF格式创建.obj文件,然后将它们与gcc链接:
gcc -m32 -nostdlib -nodefaultlibs -lgcc os.obj helper.obj -t linker.ld
Run Code Online (Sandbox Code Playgroud)
与此链接文件:
ENTRY(_start)
SECTIONS
{
. = 0x7C00;
.text :
{
*(.text);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试运行.bin已创建的时,qemu无法识别该文件。我做错了什么?
(我使用过gcc是因为我计划将来使用C代码)
实际上,我什至不知道gcc中所有标志的作用。我已经从Internet XD复制了它们。
到目前为止,这是我所做的:
nasm -f elf os.asm -o os.obj
nasm -f elf helper.asm -o helper.obj
gcc -m32 -nostdlib -nodefaultlibs -lgcc os.obj helper.obj -t linker.ld -o myos.bin
objcopy --input-target=elf32-little --output-target=binary myos.bin myos.bin.new
qemu-system-x86_64 myos.bin.new …Run Code Online (Sandbox Code Playgroud) Linux 如何通过系统调用确定要执行的另一个进程的地址?就像在这个例子中一样?
mov rax, 59
mov rdi, progName
syscall
Run Code Online (Sandbox Code Playgroud)
我的问题似乎有点混乱,澄清一下,我问的是系统调用是如何工作的,与传递的寄存器或参数无关。当另一个进程被调用时,它如何知道跳转、返回等位置。
我有一个用nasm编译的示例程序集文件:
nasm -f elf syscall.asm
Run Code Online (Sandbox Code Playgroud)
这会生成一个syscall.o文件.我尝试将它与ld链接:
ld -o syscall syscall.o
Run Code Online (Sandbox Code Playgroud)
ld命令失败,并显示以下错误:
ld: i386 architecture of input file `syscall.o' is incompatible with i386:x86-64 output
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做
ld -o syscall syscall.o -melf_i386
Run Code Online (Sandbox Code Playgroud)
命令成功,我得到一个系统调用可执行文件.
弄清楚nasm没有生成x86-64格式的目标代码我在syscall.asm文件的开头添加了"BITS 64"指令.
然后尝试使用nasm组装syscall.asm会出现以下错误:
error: elf output format does not support 64-bit code
Run Code Online (Sandbox Code Playgroud)
这看起来很奇怪,因为在我的终端上执行"file/usr/bin/nasm"会给出:
/usr/bin/nasm: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
Run Code Online (Sandbox Code Playgroud)
我的64位Fedora Core 11安装了最新版本的nasm,我的CPU是Intel Core 2 Duo E7200.
[编辑]
我的问题是如何让nasm发出与i386兼容的目标文件:x86-64.
我在ubuntu下使用nasm.顺便说一下,我需要从用户的键盘上获取单个输入字符(比如一个程序要求你输入y/n?)所以当按下键并且没有按下输入时我需要读取输入的字符.我搜索了很多,但我发现的所有内容都与此行(int 21h)有关,导致"分段错误".请帮我弄清楚如何获得单个字符或如何克服这个分段错误.