小编Sep*_*and的帖子

8086 汇编语言程序从 A 到 Z 打印

我有以下程序,可以从 A 打印到 Z,中间有一个空格。在下面的程序中,我理解了其余的代码,但不明白为什么使用PUSH DX和指令。POP DX如果我运行代码而不使用PUSH DXand POP DX,它只会打印“!” 而不是角色。

.model small
.stack
.data
    VAL DB 'A'

.code
    MAIN PROC
        SPACE MACRO
            MOV DL, ' '
            MOV AH, 02h;
            INT 21H    
        ENDM
        
        MOV AX, @DATA
        MOV DS, AX
        
        MOV CL, 26
        MOV DL, 65 ; MOV DL, VAL
        
        PRINT:
            MOV AH, 02H
            INT 21H
            PUSH DX
            SPACE
            POP DX
            INC DL
            DEC CL
            JNZ PRINT
            
        MOV AH, 4CH
        INT 21H        
            
    MAIN ENDP
    END …
Run Code Online (Sandbox Code Playgroud)

assembly stack dos cpu-registers x86-16

2
推荐指数
1
解决办法
2万
查看次数

Intel 8086:为什么有 4 个内存段

据我了解,8086处理器有4个内存段:堆栈段、代码段、数据段和额外段,以及相应的段寄存器(SS, CS, DS, ES

问题是:“为什么?”
为什么不将数据段和代码段结合起来?
为什么我们需要额外的段?
为什么是4?

我知道这个问题可能听起来很无聊,但我在去年在我的大学进行的一次“微处理器架构”考试中发现了这个问题。

提前致谢。

cpu-architecture cpu-registers x86-16

2
推荐指数
1
解决办法
1361
查看次数

在 x86 汇编中交换 2 个整数

我有一个指向整数数组开头的整数指针,并且我正在尝试交换程序集 x86 中的两个值。这是我的代码:

movq (%rdi,%rcx,4),%r8     # SWAP
movq 4(%rdi,%rcx,4),%r9   
movq %r9,(%rdi,%rcx,4)
movq %r8,4(%rdi,%rcx,4)
Run Code Online (Sandbox Code Playgroud)

rdi包含指针,并且两个值的地址计算是正确的(rcx第一次迭代中只是 0),但是,这是我进行交换时发生的情况:

(gdb) x/5wd $rdi
0x602010:    31    1    2    3
0x602020:    0
(gdb) x/5wd $rdi
0x602010:    1     2    2    3
0x602020:    0
(gdb) x/5wd $rdi
0x602010:    1     31    2    3
0x602020:    0
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,第三个值被第一个和第二个值的交换所替换,我不明白为什么。关于我应该在哪里寻找错误的任何建议?

c assembly swap x86-64

2
推荐指数
1
解决办法
652
查看次数

将 xmm 寄存器的低两个 32 位浮点数扩展为整个 xmm 寄存器

Intel x86 汇编中执行以下操作的最有效方法是什么(ab是 32 位浮点数):

xmm1: [-, -, a, b]xmm1: [a, a, b, b]

我找不到任何有用的说明。
我的想法是将ab复制到其他寄存器,然后将xmm1寄存器移动 4 个字节并将ab移动到最低的 4 个字节。

x86 assembly sse

2
推荐指数
1
解决办法
83
查看次数

为什么要让一些寄存器由调用者保存而另一些寄存器由被调用者保存?为什么不让调用者保存它想要保存的所有内容?

在这篇关于寄存器保存的维基百科文章中,我读到调用者函数负责某些寄存器(以防止其先前的数据被更改),而被调用者则负责其他寄存器。

我的问题是为什么我们必须让事情复杂化?为什么不让所有寄存器成为调用者的责任,在调用函数之前备份现有值并在之后重新加载它们?

我没有看到执行这些步骤有任何性能提升,有人可以帮助我理解吗?

assembly cpu-registers calling-convention riscv

2
推荐指数
1
解决办法
2073
查看次数

JZ是不是在栈里放了一个返回地址?

我正在阅读汇编代码优化手册第 2.3 节常见编码陷阱 - 第 9 页

  1. 无与伦比的 PUSH 和 POP 指令。对于通过函数的所有可能路径,PUSH 和 POP 指令的数量必须相等。例子:

    push ebx
    test ecx, ecx
    jz   Finished
    ...
    pop  ebx
    Finished:       ; Wrong! Label should be before pop ebx
    ret
    
    Run Code Online (Sandbox Code Playgroud)

这里,如果 ECX 为零,则不会再次弹出推送的 EBX 值。结果是RET指令会弹出EBX之前的值并跳转到错误的地址。

我的疑问是:jz指令不是将返回地址存储在堆栈中吗?什么其他指令一样jmpjgjgejljle等?

x86 assembly

2
推荐指数
1
解决办法
54
查看次数

如何使用静态数组的结束指针作为循环条件来比较 x86 中的地址?

从头开始编程的挑战之一是“修改程序以使用结束地址而不是数字 0 来知道何时停止。”

\n

我发现很难做到这一点,因为到目前为止,这本书只介绍了movl,,cmplincl以及寻址模式)和jmp指令。基本上,下面的代码片段中的所有内容都是到目前为止所介绍的。我发现的所有解决方案都涉及本书中尚未介绍的说明。下面的代码查找集合中的最大值。

\n
.section .data\ndata_items:             #These are the data items\n.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0\n\n.section .text\n.globl _start\n_start:\n    movl $0, %edi                   # move 0 into the index register\n    movl data_items(,%edi,4), %eax  # load the first byte of data\n    movl %eax, %ebx                 # since this is the first item, %eax is\n                                    # the biggest\nstart_loop:                     # start loop\n    cmpl $0, %eax                   # check to see if we\xe2\x80\x99ve hit the end\n    je loop_exit\n    incl %edi                       # …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly pointers att

2
推荐指数
1
解决办法
278
查看次数

计算DW数组中等于1的元素数量

我想计算数组中 1 的数量(使用 MASM32)。在第一次迭代中,我在EAX. 我得到的不是 00000000,而是 00010000。因此,计数器中的值也不正确ECX

.386  
.model small  
.data  
var1 dw 0,1,1 
.code  
main PROC  
   LEA ESI, var1  
   MOV EBX, 3  
   MOV ECX, 0  
L1:CMP EBX, 0  
   JE L3  
   MOV EAX, [ESI]  
   CMP EAX, 0  
   JE L2  
   INC ECX  
L2:DEC EBX  
   ADD ESI, 2  
   JMP L1  
L3:INVOKE ExitProcess, 0  
main ENDP  
END main  
Run Code Online (Sandbox Code Playgroud)

看这个图片,得到 00010000EAX而不是 00000000 因为内容在[ESI] 开始时是 0

看到此图像在 EAX 中获取 00010000 而不是 0000000,因为 ESI 内容在开始时为 0

x86 assembly masm masm32

2
推荐指数
1
解决办法
221
查看次数

为什么使用向量寄存器而不是将 stdargs 保存在堆栈中?

所以我正在阅读 SYSTEM V AMD64 ABI,其中写道我们必须使用向量寄存器来保存 stdargs 并设置AL为用于放置参数的寄存器的数量。
为什么需要使用向量寄存器?我们不能将它们放入堆栈并将AL寄存器设置为堆栈中的参数数量吗?

assembly x86-64 calling-convention

2
推荐指数
1
解决办法
167
查看次数

为什么我在 proteus 中收到此错误:“PC=0x002A 处的操作码 0xFFFF 无效”

我用汇编语言为 avr atmega328P 编写了这段代码。它使用按钮打开和关闭 LED,但在 proteus 中我收到此错误:

PC=0x002A 处的无效操作码 0xFFFF

这是我的代码:

.INCLUDE "M328Pdef.inc"


ldi r16,HIGH(RAMEND)
out SPH, R16
ldi r16,LOW(RAMEND)
out SPL, R16

start:
ldi r16,0xFF
out DDRB,r16
ldi r17,0x00
out DDRD,r17
ldi r21,0x00
ldi r23,0x01

Forever:
in r20,PIND
cp r20,r21
BREQ ledon
cp r20,r23
BREQ ledoff
rjmp Forever


ledon:
ldi r22,0x01
out PORTB,r22 
ret

ledoff:
ldi r24,0x00
out PORTB,r24
ret

Run Code Online (Sandbox Code Playgroud)

有人有解决办法吗?

microcontroller assembly avr atmega32

2
推荐指数
1
解决办法
2634
查看次数