我坚持将C代码转换为汇编.这是我需要转换的代码:
#include <stdio.h>
define N 50 int x[N], y[N], z[2 * N];
void convolve(int[], int[], int[], int);
int main(void)
{
int i, n;
printf("Enter vector size (<=%d): ", N);
scanf("%d", &n);
printf("Enter first vector (%d elements):\n", n);
for (i = 0; i < n; i++)
**scanf("%d", &x[i]);
**printf("Enter second vector (%d elements):\n", n);
for (i = 0; i < n; i++)
scanf("%d", &y[i]);
convolve(x, y, z, n);
printf("Convolution:\n");
for (i = 0; i < ((n + n) - …Run Code Online (Sandbox Code Playgroud) 我正在进入引导程序和内核开发(非常开始)我正在关注https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev的组合 .pdf 和https://github.com/cfenollosa/os-tutorial中的代码
唯一不同的是,我的目标是x86_64而不是i386.我也使用qemu模拟(qemu-system-x86_64).现在跟随GitHub回购到第16部分视频驱动程序之后,我被卡住了,因为屏幕驱动程序确实在屏幕上打印了一些东西,但是有些事情正在发生,数据不对齐.接下来我想尝试调试我的程序.这部分也包含在回购的第14部分检查点中.所以我为目标x86_64-elf构建了gdb.但是,当我尝试运行qemu和gdb使用system-qemu-x86_64 -s -S -fda os-image
,然后运行gdb并尝试通过运行连接到qemu target remote localhost:1234,一旦我运行,我得到以下错误消息
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
Remote 'g' packet reply is too long (expected 308 bytes, got 536 bytes):
000000000000000000000000000000000000000000000000630600000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000f0ff0000000000000200000000f00000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000007f03000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000801f0000
Run Code Online (Sandbox Code Playgroud)
关于我遗失/做错的任何想法?如果需要更多信息,请告诉我.
谢谢
编辑:我已经应用了@MichaelPetch提到的补丁,现在g包错误消失了.但是看起来gdb在运行后无法解释我的可执行文件target remote localhost:1234,然后symbol-file kernel.elf …
据我所知,gcc内联汇编中使用的约束告诉gcc输入和输出变量必须(或必须),以便生成有效的汇编.正如精细手册所说,"对操作数放置的限制".
这是一个教程中特定的工作示例.
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
Run Code Online (Sandbox Code Playgroud)
inb是AT&T语法 - 代表IN从I/O端口接收一个字节的i386 指令.
以下是本指令的规格,取自i386手册.需要注意的是端口号,从去0x0000到0xFFFF.
IN AL,imm8 // Input byte from immediate port into AL
IN AX,imm8 // Input word from immediate port into AX
IN EAX,imm8 // Input dword from immediate port into EAX
IN AL,DX // Input byte from port DX into AL
IN AX,DX …Run Code Online (Sandbox Code Playgroud) 我处于以当前权限级别(CPL = 0)运行的32位保护模式.我试图通过将EFLAGS.VM(位17)标志设置为1(和IOPL为0)并对我的16位实模式代码执行FAR JMP来进入v8086模式.我使用当前的标志PUSHF; 将EFLAGS.VM(第17位)设置为1; 将EFLAGS.IOPL(第22位和第23位)设置为0; 设置新的EFLAGS POPF.这个代码看起来像:
bits 32
cli
[snip]
pushf ; Get current EFLAGS
pop eax
or eax, 1<<EFLAGS_VM_BIT ; Set VM flag to enter v8086 mode
and eax, ~(3<<EFLAGS_IOPL_BITS)
; Set IOPL to 0
; IF flag already 0 because of earlier CLI
push eax
popf ; Reload new flags
jmp CODE32_SEL:v86_mode_entry
; Far JMP to v8086 entry point
; v8086 code entry point
bits 16
v86_mode_entry:
hlt ; Halt should double fault …Run Code Online (Sandbox Code Playgroud) 在下面的例子中,我试图理解@RequestMapping 和@PostMapping 之间的区别。对于@RequestMapping:
当我通过邮递员执行POST 请求时:
http://localhost:8085/call1/initparam1?val=1111,它正确执行。但是当它通过 GET 请求
http://localhost:8085/call1/getparam1 进行时
结果我没有得到 1111。
对于@PostMapping,当我通过邮递员执行POST 请求:
http://localhost:8085/call1/initparam2/1999 时,它会正确执行。但是当它通过 GET 请求
http://localhost:8085/call1/getparam1 进行时
结果我没有得到 1999。
请向我解释使用这两种注释有什么区别,因为我花了时间谷歌搜索和研究,但我无法弄清楚为什么第一个例子不起作用。
控制器1
@Controller
@ResponseBody
@RequestMapping("/call1")
public class Call1 {
public String str = "inti";
@RequestMapping(value = "/initparam1", method = RequestMethod.POST)
public void initparam1(@RequestParam(value = "val") String val) {
this.str = val;
}
@PostMapping(value = "/initparam2/{val}")
public void initparam2(@PathVariable String val) {
this.str = val;
}
@RequestMapping("/getparam1")
@ResponseBody
public String getParam1() {
return this.str;
}
}
Run Code Online (Sandbox Code Playgroud) 在Linux源代码树中,文件arch/x86/boot/header.S具有类似于此的x86代码,以便在被调用之前清除BSS部分main:
...
# Zero the bss
movw $__bss_start, %di
movw $_end+3, %cx
xorl %eax, %eax
subw %di, %cx
shrw $2, %cx
rep; stosl
...
Run Code Online (Sandbox Code Playgroud)
为什么_end地址中添加了3个?为什么不movw $_end, %cx代替movw $_end+3, %cx?
例如,使用BIOS打印a到屏幕的引导扇区main.asm:
org 0x7c00
bits 16
cli
mov ax, 0x0E61
int 0x10
hlt
times 510 - ($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
然后:
nasm -o main.img main.asm
qemu-system-i386 -hda main.img -S -s &
gdb -ex 'target remote localhost:1234' \
-ex 'break *0x7c00' \
-ex 'continue' \
-ex 'x/3i $pc'
Run Code Online (Sandbox Code Playgroud)
我明白了:
0x7c00: cli
0x7c01: mov $0x10cd0e61,%eax
0x7c06: hlt
Run Code Online (Sandbox Code Playgroud)
所以看起来它mov ax, 0x0E61被解释为32位mov %eax并且将下一条指令int 0x10作为数据.
我怎么能告诉GDB这是16位代码?
也可以看看:
objdump" https://www.sourceware.org/ml/gdb/2007-03/msg00308.html,如下所示:如何反汇编原始x86代码?也许这是在实施的同时实施的?我正在尝试创建一个Spring Boot项目.
pom.xml中:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.java</groupId>
<artifactId>spring-boot-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Java Spring Boot Example</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
Run Code Online (Sandbox Code Playgroud)
SpringBootExample.java:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootExample {
public static void main(String[] args) {
SpringApplication.run(SpringBootExample.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
当尝试将上述类作为Java应用程序执行时,我收到错误:
2017-06-21 17:07:14.125 ERROR 7860 --- [main] osbfsDefaultListableBeanFactory:名为'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory'的bean上的Destroy方法引发异常
java.lang.IllegalStateException:ApplicationEventMulticaster未初始化 - 在通过上下文组播事件之前调用'refresh':org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@63f509:启动日期[Wed Jun 21 17:07:06 EDT 2017]; org.springframework.context.support上的org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:404)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]中的上下文层次结构的根org.springframework.beans.factory.support.DisposableBeanAdapter.destroy中的.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97)〜[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE](DisposableBeanAdapter.java: 253)〜[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)[spring-beans-4.3. 4.RELEASE.jar:4.3.4.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)[spring-beans-4.3.4.RELEASE.jar:4.3.4.发布在org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListable)BeanFactory.java:954)[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)[spring-beans] -4.3.4.RELEASE.jar:4.3.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:961)[spring-beans-4.3.4.RELEASE.jar:4.3 .4.RELEASE]在org.springframework.context的org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]. support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:555)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java: …
在以下 x86 汇编代码中:
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002+0x00)
Run Code Online (Sandbox Code Playgroud)
这些值似乎没有分配给任何变量。那么这段代码有什么作用呢?我听说过它被存储在内存中,但具体在哪里呢?
有人可以解释为什么这个代码:
#include <stdio.h>
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用tcc使用tcc编译时,生成这个asm:
00401000 |. 55 PUSH EBP
00401001 |. 89E5 MOV EBP,ESP
00401003 |. 81EC 00000000 SUB ESP,0
00401009 |. 90 NOP
0040100A |. B8 00000000 MOV EAX,0
0040100F |. E9 00000000 JMP fmt_vuln1.00401014
00401014 |. C9 LEAVE
00401015 |. C3 RETN
Run Code Online (Sandbox Code Playgroud)
我猜可能是
00401009 |. 90 NOP
Run Code Online (Sandbox Code Playgroud)
也许有一些内存对齐,但是怎么样
0040100F |. E9 00000000 JMP fmt_vuln1.00401014
00401014 |. C9 LEAVE
Run Code Online (Sandbox Code Playgroud)
我的意思是为什么编译器会插入跳转到下一条指令的近跳转,LEAVE会执行呢?
我在64位Windows上使用TCC 0.9.26生成32位可执行文件.
x86 ×8
assembly ×5
osdev ×4
c ×2
gcc ×2
gdb ×2
nasm ×2
qemu ×2
spring ×2
spring-boot ×2
bootloader ×1
disassembly ×1
g++ ×1
java ×1
kernel ×1
linux ×1
linux-kernel ×1
multiboot ×1
tcc ×1
x86-64 ×1