因为我对汇编很新,所以如果用户在汇编中输入大写字母或反之亦然,我有一些关于如何从小写转换为大写的问题.这是我到目前为止:
section .data
Enter db "Enter: "
Enter_Len equ $-Enter
Output db "Output: "
Output_Len equ $-Output
Thanks db "Thanks!"
Thanks_Len equ $-Thanks
Loop_Iter dd 0 ; Loop counter
section .bss
In_Buffer resb 2
In_Buffer_Len equ $-In_Buffer
section .text
global _start
_start:
; Print Enter message
mov eax, 4 ; sys_write
mov ebx, 1
mov ecx, Enter
mov edx, Enter_Len
int 80h
; Read input
mov eax, 3 ; sys_read
mov ebx, 0
mov ecx, In_Buffer
mov edx, In_Buffer_Len
int …Run Code Online (Sandbox Code Playgroud) 我在linux x86_64上构建了一个用C和内联汇编编写的简短程序.它应该写一个字符串给stdout.我在互联网上的一篇文章中找到了它:
int write_call( int fd, const char * str, int len ){
long __res;
__asm__ volatile ( "int $0x80":
"=a" (__res):"0"(__NR_write),"b"((long)(fd)),"c"((long)(str)),"d"((long)(len)) );
return (int) __res;
}
void do_write( void ){
char * str = "Paragon output string.\n";
int len = strlen( str ), n;
printf( "string for write length = %d\n", len );
n = write_call( 1, str, len );
printf( "write return : %d\n", n );
}
int main( int argc, char * argv[] ){
do_write();
return EXIT_SUCCESS; …Run Code Online (Sandbox Code Playgroud) 如何在内联汇编gcc中读取stdin并写入stdout,就像我们在NASM中这样做:
_start:
mov ecx, buffer ;buffer is a data word initialised 0h in section .data
mov edx, 03
mov eax, 03 ;read
mov ebx, 00 ;stdin
int 0x80
;Output the number entered
mov eax, 04 ;write
mov ebx, 01 ;stdout
int 0x80
Run Code Online (Sandbox Code Playgroud)
我尝试从内联汇编中的stdin读取,然后将输入分配给x:
#include<stdio.h>
int x;
int main()
{
asm(" movl $5, %%edx \n\t" "
movl $0, %%ebx \n\t" "
movl $3, %%eax \n\t" "
int $0x80 \n\t "
mov %%ecx,x"
::: "%eax", "%ebx", "%ecx", "%edx");
printf("%d",x);
return 0;
} …Run Code Online (Sandbox Code Playgroud) 我对 Linux 的 nanosleep 系统调用有一些问题。此代码应等待 2 秒才退出,但事实并非如此:
.text
.globl _start
_start:
pushq %rbp
movq %rsp,%rbp
pushq $0 #0 nanoseconds
pushq $2 #2 seconds
leaq (%rbp),%rdi #the time structure on the stack
movq $35,%rax #nanosleep syscall
movq $0,%rsi #disable useless parameter
syscall
leave
Run Code Online (Sandbox Code Playgroud) 我想让 Linux 只使用 sys_read 从键盘上进行 1 次击键,但 sys_read 只是等到我按下 Enter 键。如何读取 1 个按键?这是我的代码:
Mov EAX,3
Mov EBX,0
Mov ECX,Nada
Mov EDX,1
Int 80h
Cmp ECX,49
Je Do_C
Jmp Error
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用 BIOS 中断但它失败了(分段错误),我想从键盘捕获数字 1 到 8 输入。
我最近涉足低级编程,并希望制作一个somesyscall接受(CType rax, CType rbx, CType rcx, CType rdx). struct CType 看起来像:
/*
TYPES:
0 int
1 string
2 bool
*/
typedef struct {
void* val;
int typev;
} CType;
Run Code Online (Sandbox Code Playgroud)
该功能有点混乱,但理论上应该可以工作:
#include <errno.h>
#include <stdbool.h>
#include "ctypes.h"
//define functions to set registers
#define seteax(val) asm("mov %0, %%rax" :: "g" (val) : "%rax")
#define setebx(val) asm("mov %0, %%rbx" :: "g" (val) : "%rbx")
#define setecx(val) asm("mov %0, %%rcx" :: "g" (val) : "%rcx")
#define setedx(val) asm("mov %0, %%rdx" …Run Code Online (Sandbox Code Playgroud) 我正在组装中构建一个32位操作系统.
我已经设置了IDT,我正在通过int指令处理程序interruptus .
如何启用syscall和sysenter说明以及如何处理/返回?
诚然,syscall指令在32位基于英特尔处理器的支持,所以我不能用它?sysret教学不安全是真的吗?在某处存在一个教程吗?
编辑:我的主要问题是如何启用syscall和sysenter说明!(没有重复)
assembly system-calls protected-mode osdev interrupt-handling
幸运的是,学习计算机编程艺术的所有用途都可以访问Stack Overflow等社区!我决定承担学习如何编程计算机的任务,我正在通过一本名为"从头开始编程"的电子书的知识这样做,该电子书教会读者如何用汇编语言创建程序在GNU/Linux环境中.
我在本书中的进展已经到了创建一个程序,该程序用函数计算整数4的阶乘,我已经完成并完成了没有由GCC的汇编程序引起的或由运行程序引起的任何错误.但是,我的程序中的功能没有返回正确的答案!阶乘4是24,但程序返回值0!说对了,我不知道为什么会这样!
以下是供您考虑的代码:
.section .data
.section .text
.globl _start
.globl factorial
_start:
push $4 #this is the function argument
call factorial #the function is called
add $4, %rsp #the stack is restored to its original
#state before the function was called
mov %rax, %rbx #this instruction will move the result
#computed by the function into the rbx
#register and will serve as the return
#value
mov $1, %rax #1 must be placed inside this register for
#the exit system …Run Code Online (Sandbox Code Playgroud) 我已经做了这个代码:
global strlen
; int strlen(const char *string);
strlen:
xor rcx, rcx
retry:
cmp byte [rdi + rcx], 0
je result
inc rcx
jmp retry
result:
mov rax, rcx
ret
Run Code Online (Sandbox Code Playgroud)
这就是我测试它的方式:
#include <stdio.h>
int main(int argc, char **argv)
{
char* bob = argv[1];
printf("%i\n", strlen(bob));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个有效的 strlen,这里没问题,但我注意到我可以rdi在重试块的第一行切换arax而不改变任何东西,我不知道这是否是正常行为。我应该保留哪些值?
我知道这int 0x80会在 linux 中造成中断。但是,我不明白这段代码是如何工作的。它会返回一些东西吗?
代表什么$ - msg?
global _start
section .data
msg db "Hello, world!", 0x0a
len equ $ - msg
section .text
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, len
int 0x80 ;What is this?
mov eax, 1
mov ebx, 0
int 0x80 ;and what is this?
Run Code Online (Sandbox Code Playgroud) 请注意,这个问题在这里已经有类似的答案,我想指出:
然而,这个问题更多地询问它们的返回格式以及它们如何相互关联(我认为上面的问题没有完全涵盖)。
_start和之间有什么区别main?在我看来,像ld用途_start,但gcc用途main为切入点。我注意到的另一个区别是main似乎返回值 in %rax,而_start返回值 in%rbx
以下是我看到的两种方式的示例:
.globl _start
_start:
mov $1, %rax
mov $2, %rbx
int $0x80
Run Code Online (Sandbox Code Playgroud)
并运行它:
$ as script.s -o script.o; ld script.o -o script; ./script; echo $?
# 2
Run Code Online (Sandbox Code Playgroud)
另一种方式:
.globl main
main:
mov $3, %rax
ret
Run Code Online (Sandbox Code Playgroud)
并运行它:
$ gcc script.s -o script; ./script; echo $?
3
Run Code Online (Sandbox Code Playgroud)
这两种方法有什么区别?是否main自动调用_start某处,或者它们如何相互关联?为什么一个返回它们的值,rbx而另一个返回它的值rax …
我是汇编新手,从我了解到的情况.code与 相同.text,但下面的代码将使用.code.
segment .data
msg db "hello, world", 0xa
len equ $ - msg
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
Run Code Online (Sandbox Code Playgroud)
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
hello, world
sed -i s/.text/.code/ ./hello.s
nasm -f elf64 -o hello.o hello.s
ld -s -o hello hello.o
./stack.sh: line 8: 4621 Segmentation …Run Code Online (Sandbox Code Playgroud)